Project: titanium
Issue TIMOB-18082: Android: Enable --multi-dex for android builds
h4. Problem Titanium tooling will not build a project that has more than 65536 total method calls Currently android has a limit on the number of methods permitted in a single dex file. (65536 - who thought a short int should be used here???) As an example, the latest google-play-services.jar from 3.4.1 has 23600. For basic S3 support from aws 2.0, a module uses 26800. By the time you build an empty titanium app you are left with: {code} [ERROR] trouble writing output: Too many method references: 68927; max is 65536. {code} h4. Solution The solution is to use the --multi-dex option in calling dexer. The problem will be that --multi-dex cant just be dropped in as it requires a different output. A decision will need to be made on how to modify this.buildBinClassesDex. Example (~2952) {code} dexArgs = [ '-Xmx' + this.dxMaxMemory, '-XX:-UseGCOverheadLimit', '-Djava.ext.dirs=' + this.androidInfo.sdk.platformTools.path, '-jar', this.androidInfo.sdk.dx, '--dex', '--multi-dex', '--output=' + this.buildBinClassesDex, this.buildBinClassesDir, path.join(this.platformPath, 'lib', 'titanium-verify.jar') {code} In this case, if this.buildBinClassesDex points to a directory (lets say this.buildBinDir) we end up with our 2 .dex files {code} -rw-r--r-- 1 stephenfeather 8276656 Nov 21 16:53 classes.dex -rw-r--r-- 1 stephenfeather 633200 Nov 21 16:53 classes2.dex {code} Around like 4029 we can add a hack to push the other .dex file into our package. This would need to be coded to scan the directory for all *.dex files and add them to the bundle. {code} dest.append(fs.createReadStream(path.join(this.buildBinDir, 'classes.dex')), { name: 'classes.dex' }); dest.append(fs.createReadStream(path.join(this.buildBinDir, 'classes2.dex')), { name: 'classes2.dex' }); {code} The problem however, is that the app will not run on a device because we would need to tell the application loader that this is a multidex package which will require another ticket. https://developer.android.com/reference/android/support/multidex/MultiDexApplication.html {code} [WARN] dalvikvm: Unable to resolve superclass of Lorg/appcelerator/titanium/TiBaseActivity; (802) [WARN] dalvikvm: Link of class 'Lorg/appcelerator/titanium/TiBaseActivity;' failed [WARN] dalvikvm: Unable to resolve superclass of Lorg/appcelerator/titanium/TiLaunchActivity; (7431) [WARN] dalvikvm: Link of class 'Lorg/appcelerator/titanium/TiLaunchActivity;' failed [WARN] dalvikvm: Unable to resolve superclass of Lorg/appcelerator/titanium/TiRootActivity; (7445) [WARN] dalvikvm: Link of class 'Lorg/appcelerator/titanium/TiRootActivity;' failed [WARN] dalvikvm: VFY: unable to [WARN] dalvikvm: VFY: Ljava/lang/Object; is not instance of Landroid/app/Activity; [WARN] dalvikvm: VFY: bad arg 1 (into Landroid/app/Activity;) [WARN] dalvikvm: VFY: rejecting call to Lorg/appcelerator/titanium/TiVerify;. (Landroid/app/Activity;Lorg/appcelerator/titanium/TiApplication;)V [WARN] dalvikvm: VFY: rejecting opcode 0x70 at 0x0002 [WARN] dalvikvm: VFY: rejected Lcom/stephenfeather/test/classic/TestingClassicApplication;.verifyCustomModules (Lorg/appcelerator/titanium/TiRootActivity;)V [WARN] dalvikvm: Verifier rejected class Lcom/stephenfeather/test/classic/TestingClassicApplication; [WARN] dalvikvm: Class init failed in newInstance call (Lcom/stephenfeather/test/classic/TestingClassicApplication;) {code} code snippets are from _build.js
Story points: 8