├── .gitignore ├── AndroidManifest.xml ├── README.md ├── ic_launcher-web.png ├── jni ├── Android.mk ├── LinearAllocFix.c └── LinearAllocFix.h ├── libs └── armeabi │ └── liblinear-alloc-fix.so ├── proguard-project.txt ├── project.properties ├── res ├── drawable-hdpi │ └── ic_launcher.png ├── drawable-mdpi │ └── ic_launcher.png ├── drawable-xhdpi │ └── ic_launcher.png ├── drawable-xxhdpi │ └── ic_launcher.png ├── layout │ └── activity_main.xml └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml └── src └── info └── viila └── android └── linearallocfix ├── app └── LinearAllocFixApplication.java ├── lib ├── LinearAllocFix.class └── LinearAllocFix.java └── ui └── MainActivity.java /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .git 3 | .idea 4 | .project 5 | .settings 6 | bin 7 | gen 8 | obj 9 | *.iml 10 | -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 17 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Hack Dalvik VM解决Android 2.3 DEX/LinearAllocHdr超限 ## 2 | 3 | [link to my blog](http://viila.info/2014/04/android-2-3-dex-max-function-problem/) 4 | 5 | 配合[APKCounter](https://github.com/viilaismonster/ApkFuncCounter)使用更佳 6 | 7 | 当安卓工程庞大到一定程度(代码结构渣到一定程度)的时候,就会遇到诸如最大方法数超过限制导致无法安装,Crash等问题。 8 | 9 | 相关关键词:Android 2.3 INSTALL_FAILED_DEXOPT 65535 10 | -------------------------------------------------------------------------------- /ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viilaismonster/LinearAllocFix/e496534773a38647e741f6ec4841fd32470d2fb1/ic_launcher-web.png -------------------------------------------------------------------------------- /jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_MODULE := linear-alloc-fix 6 | LOCAL_SRC_FILES := LinearAllocFix.c 7 | 8 | LOCAL_LDLIBS := -ldl -llog 9 | 10 | include $(BUILD_SHARED_LIBRARY) -------------------------------------------------------------------------------- /jni/LinearAllocFix.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "LinearAllocFix.h" 3 | #include 4 | #include 5 | #include 6 | 7 | #define LOG_TAG "*LinearAllocFix*" 8 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) 9 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) 10 | #define MEMORY_MIN 32768 11 | 12 | #define TARGET_VAL 5*1024*1024 13 | #define HACK_VAL 8*1024*1024 14 | 15 | // copy from https://github.com/android/platform_dalvik/blob/android-2.3.7_r1/vm/LinearAlloc.h#L33 16 | typedef struct LinearAllocHdr { 17 | int curOffset; /* offset where next data goes */ 18 | pthread_mutex_t lock; /* controls updates to this struct */ 19 | 20 | char* mapAddr; /* start of mmap()ed region */ 21 | int mapLength; /* length of region */ 22 | int firstOffset; /* for chasing through */ 23 | 24 | short* writeRefCount; /* for ENFORCE_READ_ONLY */ 25 | } LinearAllocHdr; 26 | 27 | int* hdrMapLength = NULL; 28 | struct LinearAllocHdr* hdr = NULL; 29 | 30 | jint JNI_OnLoad(JavaVM* vm, void* reserved) { 31 | 32 | void** ptr = (void**)MEMORY_MIN; 33 | char* line; 34 | int max = 2*MEMORY_MIN; 35 | 36 | while(max--) { 37 | if(*ptr == (void*)vm) { 38 | line = malloc(100*sizeof(char)); 39 | sprintf(line, "find VM %d = %d", ptr, *ptr); 40 | LOGI(line); 41 | free(line); 42 | } 43 | if(*(int*)ptr == TARGET_VAL) { 44 | line = malloc(100*sizeof(char)); 45 | sprintf(line, "%d = %d", ptr, *ptr); 46 | LOGE(line); 47 | free(line); 48 | hdrMapLength = (int*)ptr; 49 | hdr = (void*)(ptr-3); 50 | break; 51 | } 52 | ptr++; 53 | } 54 | 55 | if(hdr) { 56 | line = malloc(100*sizeof(char)); 57 | sprintf(line, " hdr->curOffset=%d mapLength=%d firstOffset=%d", 58 | hdr->curOffset, hdr->mapLength, hdr->firstOffset); 59 | LOGI(line); 60 | free(line); 61 | } 62 | 63 | return JNI_VERSION_1_4; 64 | } 65 | 66 | JNIEXPORT jlong JNICALL Java_info_viila_android_linearallocfix_lib_LinearAllocFix_current( 67 | JNIEnv * env, 68 | jobject context) { 69 | 70 | if(!hdrMapLength) 71 | return -1; 72 | 73 | return *hdrMapLength; 74 | } 75 | 76 | JNIEXPORT jlong JNICALL Java_info_viila_android_linearallocfix_lib_LinearAllocFix_hack( 77 | JNIEnv * env, 78 | jobject context) { 79 | 80 | if(!hdrMapLength) 81 | return -1; 82 | 83 | pthread_mutex_lock(&hdr->lock); 84 | 85 | *hdrMapLength = HACK_VAL; 86 | hdr->mapAddr = mmap(NULL, hdr->mapLength, PROT_READ | PROT_WRITE, 87 | MAP_PRIVATE | MAP_ANON, -1, 0); 88 | 89 | pthread_mutex_unlock(&hdr->lock); 90 | 91 | return *hdrMapLength; 92 | } 93 | 94 | 95 | JNIEXPORT jlong JNICALL Java_info_viila_android_linearallocfix_lib_LinearAllocFix_debug( 96 | JNIEnv * env, 97 | jobject context, 98 | jint offset, jint attr) { 99 | 100 | return -1; 101 | } 102 | -------------------------------------------------------------------------------- /jni/LinearAllocFix.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | /* Header for class info_viila_android_linearallocfix_lib_LinearAllocFix */ 4 | 5 | #ifndef _Included_info_viila_android_linearallocfix_lib_LinearAllocFix 6 | #define _Included_info_viila_android_linearallocfix_lib_LinearAllocFix 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | /* 12 | * Class: info_viila_android_linearallocfix_lib_LinearAllocFix 13 | * Method: current 14 | * Signature: ()I 15 | */ 16 | JNIEXPORT jlong JNICALL Java_info_viila_android_linearallocfix_lib_LinearAllocFix_current 17 | (JNIEnv *, jobject); 18 | 19 | /* 20 | * Class: info_viila_android_linearallocfix_lib_LinearAllocFix 21 | * Method: debug 22 | * Signature: ()I 23 | */ 24 | JNIEXPORT jlong JNICALL Java_info_viila_android_linearallocfix_lib_LinearAllocFix_hack 25 | (JNIEnv *, jobject); 26 | 27 | /* 28 | * Class: info_viila_android_linearallocfix_lib_LinearAllocFix 29 | * Method: hack 30 | * Signature: ()I 31 | */ 32 | JNIEXPORT jlong JNICALL Java_info_viila_android_linearallocfix_lib_LinearAllocFix_debug 33 | (JNIEnv *, jobject, jint, jint); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | #endif 39 | -------------------------------------------------------------------------------- /libs/armeabi/liblinear-alloc-fix.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viilaismonster/LinearAllocFix/e496534773a38647e741f6ec4841fd32470d2fb1/libs/armeabi/liblinear-alloc-fix.so -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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-17 15 | android.library=true 16 | -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viilaismonster/LinearAllocFix/e496534773a38647e741f6ec4841fd32470d2fb1/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viilaismonster/LinearAllocFix/e496534773a38647e741f6ec4841fd32470d2fb1/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viilaismonster/LinearAllocFix/e496534773a38647e741f6ec4841fd32470d2fb1/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viilaismonster/LinearAllocFix/e496534773a38647e741f6ec4841fd32470d2fb1/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 |