├── 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 |
--------------------------------------------------------------------------------