├── Dex65536 ├── pathtool.jar ├── libs │ ├── 10k-methods.jar │ └── android-support-v4.jar ├── res │ ├── drawable-hdpi │ │ └── ic_launcher.png │ ├── drawable-mdpi │ │ └── ic_launcher.png │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ ├── values │ │ ├── strings.xml │ │ └── styles.xml │ ├── values-v11 │ │ └── styles.xml │ ├── values-v14 │ │ └── styles.xml │ └── layout │ │ └── activity_main.xml ├── assets │ └── dex65536.txt ├── project.properties ├── proguard-project.txt ├── AndroidManifest.xml ├── src │ └── com │ │ └── github │ │ └── mmin18 │ │ └── dex65536 │ │ ├── MainActivity.java │ │ └── App.java ├── build.xml └── custom_rules.xml ├── Lib ├── res │ └── values │ │ └── strings.xml ├── AndroidManifest.xml ├── src │ └── com │ │ └── github │ │ └── mmin18 │ │ └── dex65536 │ │ └── HelloTextView.java ├── project.properties ├── proguard-project.txt └── build.xml ├── .gitignore ├── LICENSE └── README.md /Dex65536/pathtool.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmin18/Dex65536/HEAD/Dex65536/pathtool.jar -------------------------------------------------------------------------------- /Dex65536/libs/10k-methods.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmin18/Dex65536/HEAD/Dex65536/libs/10k-methods.jar -------------------------------------------------------------------------------- /Dex65536/libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmin18/Dex65536/HEAD/Dex65536/libs/android-support-v4.jar -------------------------------------------------------------------------------- /Dex65536/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmin18/Dex65536/HEAD/Dex65536/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Dex65536/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmin18/Dex65536/HEAD/Dex65536/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Dex65536/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmin18/Dex65536/HEAD/Dex65536/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Dex65536/assets/dex65536.txt: -------------------------------------------------------------------------------- 1 | assets/libs.apk will be generate and package to your final apk file. 2 | https://github.com/mmin18/Dex65536 3 | -------------------------------------------------------------------------------- /Lib/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Hello, this is the string from android library project, just to check if the R.java works. 4 | 5 | -------------------------------------------------------------------------------- /Dex65536/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dex65536 4 | This apk contains more than 65536 methods. Normally the dalvik compiler will fail, but the custom_rules.xml can separate them into two .dex file and make it runnable. 5 | 6 | 7 | -------------------------------------------------------------------------------- /Lib/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Dex65536/res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Dex65536/res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Eclipse project files 19 | .classpath 20 | .project 21 | 22 | # Proguard folder generated by Eclipse 23 | proguard/ 24 | 25 | # Intellij project files 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | -------------------------------------------------------------------------------- /Lib/src/com/github/mmin18/dex65536/HelloTextView.java: -------------------------------------------------------------------------------- 1 | package com.github.mmin18.dex65536; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.widget.TextView; 6 | 7 | import com.github.mmin18.dex65536.lib.R; 8 | 9 | public class HelloTextView extends TextView { 10 | 11 | public HelloTextView(Context context, AttributeSet attrs) { 12 | super(context, attrs); 13 | 14 | setText(R.string.hello); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /Lib/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-19 15 | android.library=true 16 | -------------------------------------------------------------------------------- /Dex65536/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-16 15 | android.library.reference.1=../Lib 16 | -------------------------------------------------------------------------------- /Dex65536/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Lib/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /Dex65536/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /Dex65536/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 16 | 17 | 23 | 24 | -------------------------------------------------------------------------------- /Dex65536/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 mmin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Dex65536/src/com/github/mmin18/dex65536/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.github.mmin18.dex65536; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | import android.os.Bundle; 6 | import android.os.Handler; 7 | import android.os.Message; 8 | import android.support.v4.app.FragmentActivity; 9 | import android.widget.TextView; 10 | 11 | public class MainActivity extends FragmentActivity { 12 | Class curC; 13 | int curI; 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_main); 19 | 20 | new Thread() { 21 | @Override 22 | public void run() { 23 | Class[] cs = new Class[] { 24 | com.github.mmin18.methodpool1.A.class, 25 | com.github.mmin18.methodpool1.B.class, 26 | com.github.mmin18.methodpool1.C.class, 27 | com.github.mmin18.methodpool1.D.class, 28 | com.github.mmin18.methodpool1.E.class, 29 | com.github.mmin18.methodpool1.F.class, 30 | com.github.mmin18.methodpool2.A.class }; 31 | 32 | for (Class c : cs) { 33 | curC = c; 34 | try { 35 | Object instance = c.newInstance(); 36 | for (curI = 0; curI < 10000; curI++) { 37 | Method m = c.getDeclaredMethod("method_" + curI); 38 | m.invoke(instance); 39 | } 40 | } catch (Exception e) { 41 | throw new RuntimeException("Fail to load class " + c, e); 42 | } 43 | } 44 | 45 | curI = -1; 46 | } 47 | }.start(); 48 | 49 | new Handler() { 50 | @Override 51 | public void handleMessage(Message msg) { 52 | TextView text = (TextView) findViewById(R.id.progress); 53 | if (curI != -1) { 54 | text.setText(curC + " / " + curI); 55 | sendEmptyMessageDelayed(1, 100); 56 | } else { 57 | text.setText("DONE"); 58 | } 59 | } 60 | }.sendEmptyMessage(1); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Dex65536/src/com/github/mmin18/dex65536/App.java: -------------------------------------------------------------------------------- 1 | package com.github.mmin18.dex65536; 2 | 3 | import java.io.File; 4 | import java.io.FileOutputStream; 5 | import java.io.InputStream; 6 | import java.lang.reflect.Field; 7 | 8 | import android.annotation.SuppressLint; 9 | import android.app.Application; 10 | import android.content.pm.ApplicationInfo; 11 | import android.os.Build; 12 | import dalvik.system.DexClassLoader; 13 | 14 | public class App extends Application { 15 | 16 | @Override 17 | public void onCreate() { 18 | super.onCreate(); 19 | dexTool(); 20 | } 21 | 22 | /** 23 | * Copy the following code and call dexTool() after super.onCreate() in 24 | * Application.onCreate() 25 | *

26 | * This method hacks the default PathClassLoader and load the secondary dex 27 | * file as it's parent. 28 | */ 29 | @SuppressLint("NewApi") 30 | private void dexTool() { 31 | 32 | File dexDir = new File(getFilesDir(), "dlibs"); 33 | dexDir.mkdir(); 34 | File dexFile = new File(dexDir, "libs.apk"); 35 | File dexOpt = getCacheDir(); 36 | try { 37 | InputStream ins = getAssets().open("libs.apk"); 38 | if (dexFile.length() != ins.available()) { 39 | FileOutputStream fos = new FileOutputStream(dexFile); 40 | byte[] buf = new byte[4096]; 41 | int l; 42 | while ((l = ins.read(buf)) != -1) { 43 | fos.write(buf, 0, l); 44 | } 45 | fos.close(); 46 | } 47 | ins.close(); 48 | } catch (Exception e) { 49 | throw new RuntimeException(e); 50 | } 51 | 52 | ClassLoader cl = getClassLoader(); 53 | ApplicationInfo ai = getApplicationInfo(); 54 | String nativeLibraryDir = null; 55 | if (Build.VERSION.SDK_INT > 8) { 56 | nativeLibraryDir = ai.nativeLibraryDir; 57 | } else { 58 | nativeLibraryDir = "/data/data/" + ai.packageName + "/lib/"; 59 | } 60 | DexClassLoader dcl = new DexClassLoader(dexFile.getAbsolutePath(), 61 | dexOpt.getAbsolutePath(), nativeLibraryDir, cl.getParent()); 62 | 63 | try { 64 | Field f = ClassLoader.class.getDeclaredField("parent"); 65 | f.setAccessible(true); 66 | f.set(cl, dcl); 67 | } catch (Exception e) { 68 | throw new RuntimeException(e); 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Dex 65536 2 | ======== 3 | 4 | 5 | > Unable to execute dex: method ID not in [0, 0xffff]: 65536) 6 | 7 | When you get this message, normally it is not because your project itself has too much methods, but you are importing some big .jar libraries. 8 | 9 | So the easy solution is to pack your .jar libraries in libs/ folder into a secondary .dex file and load that file before your application starts. 10 | 11 | ## How to run sample project 12 | 13 | /Dex65536 is the main project, depends on a android library project /Lib. 14 | 15 | You can write code in eclipse, but you need to build/run in ant. 16 | 17 | android update project -p ./Dex65536 18 | android update project -p ./Lib 19 | cd Dex65536 20 | ant clean debug install run 21 | 22 | (Make sure your android_sdk/tools is in the $PATH) 23 | 24 | ## How to make it work on your own project 25 | 26 | ### Step1: build tools 27 | 28 | Dex65536/custom_rules.xml 29 | Dex65536/pathtool.jar 30 | 31 | Copy these two files in your android project, and execute the following command to generate build.xml. 32 | 33 | android update project -p . 34 | 35 | (Make sure your android_sdk/tools is in the $PATH) 36 | 37 | ### Step2: add some code 38 | 39 | You need to add some code to load the secondary .dex file before your application starts. 40 | 41 | public class App extends Application { 42 | 43 | @Override 44 | public void onCreate() { 45 | super.onCreate(); 46 | dexTool(); 47 | } 48 | 49 | /** 50 | * Copy the following code and call dexTool() after super.onCreate() in 51 | * Application.onCreate() 52 | *

53 | * This method hacks the default PathClassLoader and load the secondary dex 54 | * file as it's parent. 55 | */ 56 | @SuppressLint("NewApi") 57 | private void dexTool() { 58 | 59 | File dexDir = new File(getFilesDir(), "dlibs"); 60 | dexDir.mkdir(); 61 | File dexFile = new File(dexDir, "libs.apk"); 62 | File dexOpt = new File(dexDir, "opt"); 63 | dexOpt.mkdir(); 64 | try { 65 | InputStream ins = getAssets().open("libs.apk"); 66 | if (dexFile.length() != ins.available()) { 67 | FileOutputStream fos = new FileOutputStream(dexFile); 68 | byte[] buf = new byte[4096]; 69 | int l; 70 | while ((l = ins.read(buf)) != -1) { 71 | fos.write(buf, 0, l); 72 | } 73 | fos.close(); 74 | } 75 | ins.close(); 76 | } catch (Exception e) { 77 | throw new RuntimeException(e); 78 | } 79 | 80 | ClassLoader cl = getClassLoader(); 81 | ApplicationInfo ai = getApplicationInfo(); 82 | String nativeLibraryDir = null; 83 | if (Build.VERSION.SDK_INT > 8) { 84 | nativeLibraryDir = ai.nativeLibraryDir; 85 | } else { 86 | nativeLibraryDir = "/data/data/" + ai.packageName + "/lib/"; 87 | } 88 | DexClassLoader dcl = new DexClassLoader(dexFile.getAbsolutePath(), 89 | dexOpt.getAbsolutePath(), nativeLibraryDir, cl.getParent()); 90 | 91 | try { 92 | Field f = ClassLoader.class.getDeclaredField("parent"); 93 | f.setAccessible(true); 94 | f.set(cl, dcl); 95 | } catch (Exception e) { 96 | throw new RuntimeException(e); 97 | } 98 | } 99 | 100 | } 101 | 102 | If you don't have a custom Application class, register one in your AndroidManifest.xml like: 103 | 104 | 108 | 109 | Othersise you just need to copy dexTool() method into your own custom Application and call it after super.onCreate(). 110 | 111 | ### Step3: ant build and run 112 | 113 | Make sure you have ant installed. 114 | 115 | cd /YourProject 116 | ant clean debug install run 117 | 118 | Your project should be compile and runnable. Good luck. 119 | -------------------------------------------------------------------------------- /Lib/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 49 | 50 | 51 | 52 | 56 | 57 | 69 | 70 | 71 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /Dex65536/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 49 | 50 | 51 | 52 | 56 | 57 | 69 | 70 | 71 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /Dex65536/custom_rules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 20 | 21 | 27 | 28 | 29 | 33 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 48 | component: ${manifest.package}/${manifest.activity} 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 70 | component: ${manifest.package}/${manifest.activity} 71 | Debug package ${mainfest.package}. You should prepare your eclipse. 72 | Keep your project open, and if you get a red bug icon in DDMS, you 73 | should stop and manually debug it once. 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 103 | Android Ant Build. Available targets: 104 | help: Displays this help. 105 | clean: Removes output files created by other targets. 106 | This calls the same target on all dependent projects. 107 | Use 'ant nodeps clean' to only clean the local project 108 | debug: Builds the application and signs it with a debug key. 109 | The 'nodeps' target can be used to only build the 110 | current project and ignore the libraries using: 111 | 'ant nodeps debug' 112 | release: Builds the application. The generated apk file must be 113 | signed before it is published. 114 | The 'nodeps' target can be used to only build the 115 | current project and ignore the libraries using: 116 | 'ant nodeps release' 117 | instrument:Builds an instrumented package and signs it with a 118 | debug key. 119 | test: Runs the tests. Project must be a test project and 120 | must have been built. Typical usage would be: 121 | ant [emma] debug install test 122 | emma: Transiently enables code coverage for subsequent 123 | targets. 124 | install: Installs the newly build package. Must either be used 125 | in conjunction with a build target (debug/release/ 126 | instrument) or with the proper suffix indicating 127 | which package to install (see below). 128 | If the application was previously installed, the 129 | application is reinstalled if the signature matches. 130 | installd: Installs (only) the debug package. 131 | installr: Installs (only) the release package. 132 | installi: Installs (only) the instrumented package. 133 | installt: Installs (only) the test and tested packages (unless 134 | nodeps is used as well. 135 | uninstall: Uninstalls the application from a running emulator or 136 | device. Also uninstall tested package if applicable 137 | unless 'nodeps' is used as well. 138 | 139 | Custom targets: 140 | run: Run your application. 141 | rund: Run and attach to debugger. 142 | 143 | --> Example: 144 | --> ant debug install run 145 | --> ant rund 146 | 147 | 148 | 149 | --------------------------------------------------------------------------------