Android方法引用超過65535的解決方式


//在app/build.gradle

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.1"

    defaultConfig {
        ...
        minSdkVersion 14
        targetSdkVersion 24
        ...

        // 設置支持multidex
        multiDexEnabled true
    }
    ...
}

dependencies {
  compile 'com.android.support:multidex:1.0.1'
}

在application的子類(如果你需要子類的話)

package com.example;

import android.app.Application;
import android.content.Context;

/**
 * 
 */
public class MyApplication extends Application {

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
}

如果你不需要application的子類直接繼承multiDexApplication

package com.example;

import android.support.multidex.MultiDexApplication;
import android.content.Context;

/**
 * Extended MultiDexApplication 
 */
public class MyApplication extends MultiDexApplication {

     // 不需要重寫attachBaseContext()

     //..........
}

dex是Android的java代碼編譯的一種文件格式,早期的Android直接在Dalvik虛擬機中加載和執行二進制的dex文件,Android4,4以后添加一種新的應用運行模式叫ART,他會在程序運行前即安裝的時候進行一次預編譯,將dex文件轉換成機器代碼存在本地,

這種文件格式的缺點就是Android代碼的方法數量參照的單一二進制,因為文件格式的很大一部分存儲的數字是兩個字節的長度,即方法的最大數目是65535,如果一個應用的方法引用超過這個數字編譯就會失敗;

Google已經提供了一種方式叫Multidex;它包含編譯時和運行時兩個部分,從名字上可以看出來,在編譯時它會將代碼分成兩個或更多的dex文件,在運行時,它會告訴類加載器怎樣從這些dex文件中找到對應的類文件,但是這種方式也有一定的缺陷,它會增大程序啟動的時間並且在老的機器上能造成程序無響應;應該怎樣避免呢?

如果你的方法達到640000或以上,那你就應該設法減少你代碼的方法引用或是類庫中個的方法引用,怎么做呢如下: 
1,看一下程序的直接和間接的依賴關系:添加一個大型的依賴庫比你把相關的代碼導入到程序中要更好, 
2,使用ProGuard工具減少你不使用的代碼

android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile(‘proguard-android.txt'),
                    'proguard-rules.pro'
        }
    }
}
minifyEnabled true : 
The getDefaultProguardFile(‘proguard-android.txt') 默認的規則
The proguard-rules.可以自定義規則

 

Android引入第三方SDK混淆報錯shrinkDebugMultiDexComponents的解決方案

 

項目工程中,引用了一個第三方的SDK,它的jar包是已經混淆過的。在IDE下代碼編譯沒問題,但是運行在手機上就報錯。

Error:Execution failed for task ‘:app:shrinkDebugMultiDexComponents’. 
java.io.IOException: Can’t read [src\app\build\intermediates\multi-dex\debug\allclasses.jar] (Can’t process class [com/dvrcam/DvrCamSDK/a$d.class] (Unknown verification type [255] in stack map frame))

大致意思是jar包目錄com/dvrcam/DvrCamSDK/a/下的內部類d.class混淆失敗。

解決方案

在工程的根目錄下創建一個文件夾proguard,放入proguard.jar文件,下載地址:proguard.jar

在根目錄的build.gradle文件中加入 

flatDir { dirs ‘proguard’ } 和 classpath ‘proguard.io:proguard:5.2.1’

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        flatDir { dirs 'proguard' }//1.依賴庫類目錄
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.3'
        classpath 'proguard.io:proguard:5.2.1'//2.依賴的庫類
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

按照以上步驟操作,就能運行成功!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM