日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Android分包方案multidex*

發布時間:2023/12/13 综合教程 31 生活家
生活随笔 收集整理的這篇文章主要介紹了 Android分包方案multidex* 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

對于功能越來越復雜的app的兩大問題

一:我們自己應用的方法數超過了65536
我們所說的方法數限制,這個方法數包括了jar包,框架,還有我們自己應用的代碼,當我們應用的代碼超過65536時,結果如下:

我們看到,顯示我們方法的引用是65579.而引用數最大是65536,建議我們開啟分包方案。

二:我們應用的方法數沒有超過65536,但是加上依賴的jar包,框架等,超過了65536(根據方案一的結果,我們應用方法數是65579,那我們刪掉200個方法,就小于65536)

報錯如下:

三:方法數并沒有超過65536,編譯也完成了,但是在android2.3以前的系統安裝的時候,會異常中止安裝。

這個問題會發生在Android2.2以及Android 2.3的設備上,涉及到一個名為dexopt的程序,全稱dex optimization,即dex文件優化程序。在優化過程中,dexopt采用一個固定大小的緩沖區(LinearAlloc)來存儲應用中所有方法的信息,那么之所以會出現在老版本停止安裝,是因為老版本的緩沖區的大小是5M,而在新版本中,這個緩沖區的大小是8M或者16M,在老版本中更容易超過這個限制。

dexopt的執行過程是在第一次加載dex文件的時候執行的。這個過程產生了一個ODEX文件,全稱Optimised Dex。這個ODEX文件是在安裝過程中從apk里提取出的可運行文件,是優化dex產生的,再把apk包里的dex文件刪除,這樣就做到了預先提取。如果沒有ODEX文件,那么系統會從apk包中提取dex然后再運行。所以優化后可以加快軟件的啟動速度,預先提取,減少對RAM的占用。

在早期的Android系統中,dexopt會把每一個類的方法id檢索起來,存在一個鏈表結構里,而這個鏈表的長度是用一個short類型來保存的,導致方法id的數目不能夠超過65536個。雖然新版本的android系統中,dexopt修復了這個問題,但是老版本的android系統的用戶市場占有率還是占一定比例,還是不能放棄這部分用戶的,所以我們在開發中需要對老版本的這個問題進行兼容。

2.方法數越界的解決方案

插件化技術

我們可以采用動態加載部分dex,通過將一個dex拆分成兩個或多個dex,解決方法數越界的問題。

插件化是一套重量級的技術方案,我們需要通過反射來調用插件的類或方法,要使用一套插件框架來配合,而且插件化適合一些獨立的模塊,兼容性問題往往較多,如果只是用于解決方法數越界的話,并不是最好的方案。

multidex解決方案

為了解決方法數越界的問題,Google在2014年提出了multidex的解決方案,這個方案主要是針對AndroidStudio和Gradle編譯環境的,將一個dex文件拆成兩個或多個dex文件。

不過需要注意的是multidex有一個版本問題,在Android 5.0以前使用multidex需要手動引入Google提供的android-support-multidex.jar這個jar包。這個jar包我們可以在Android SDK目錄下的extras/android/support/multidex/library/libs下找到。而從Android 5.0開始,Andorid默認支持了multidex。

所以,我們就需要注意我們的SDK版本了,如果已經支持了multidex,而我們又把android-support-multidex.jar放在了項目的libs文件下,就會報錯。

3.在Gradle和代碼中配置使用Multidex

在Gradle中配置使用Multidex

由于Android的Gradle插件在Android Build Tool 21.1開始支持使用multidex,所以我們需要使用Android Build Tools 21.1及以上版本,修改app目錄下的build.gradle文件,有兩點需要修改。

(1)在defaultConfig中添加multiDexEnabled true這個配置項。
(2)在dependencies中添加multidex的依賴:
compile ‘com.android.support:multidex:1.0.0’

注意buildToolsVersion要高于21.1,配置好如下:

在Gradle中配置好之后,我們還需要在代碼中加入支持multidex的功能,有三種方案可選

方案一:在manifest文件中指定Application為MultiDexApplication,如下:

方案二:寫一個Application類并繼承MultiDexApplication,并在AndroidManifest.xml的application標簽中進行注冊(在application標簽中增加name屬性,并添加自己的Application類名即可),如果不是想重寫MultiDexApplication中一些方法的話,還是方案一更方便些。如下:

注冊如下:

方案三:如果不想按方案二繼承,我們可以重寫Application的attachBaseContext方法,注意,這個方法比onCreate方法先執行。具體方法是創建一個新類,繼承Application,然后重寫attachBaseContext方法,并在AndroidManifest.xml的application標簽中進行注冊(與方案二注冊相同)如下:

對于在AndroidManifest.xml中注冊,與方案二的注冊相同。

3.使用Multide分包后兩種情況的結果

我們的Demo圖如下,我們根據該圖和dex文件反編譯的結果分析分包情況。

情況一:方法數沒有越界
我們將方法數控制在65536以內,方法數沒有越界的話,是不會分包的,解壓apk,你會發現apk里只有一個classes.dex,如下

將其反編譯后(不知道怎么反編譯的可以看一下這篇博文:http://blog.csdn.net/gaozhan_csdn/article/details/51984056),結果如下:

可以發現,我們的類都在這個主dex文件里,并沒有分包。

情況二:方法數越界

我們再將方法數增加到65536以上。解壓apk,結果如下:

對三個dex文件反編譯一下,看看它們里面分別都包含了什么類。
classes.dex(主dex)下的類視圖:

classes2.dex的類視圖

classes3.dex的類視圖

可以發現Second類和Third類分別在classes2.dex文件和classes3.dex文件里,其他類都在主dex文件里(classes.dex),我們用multidex的確實現了分包從而解決了方法數越界的問題。

4.使用MultiDex存在的一些問題

1.Application中的靜態全局變量會比MutiDex的instal()方法優先加載,所以建議避免在Application類中使用靜態變量引用main classes.dex文件以外dex文件中的類。
或者這樣解決:

一些在二級Dex加載之前,可能會被調用到的類(比如靜態變量的類),需要放在主Dex中.否則會ClassNotFoundError. 通過修改Gradle,可以顯式的把一些類放在Main Dex中.

afterEvaluate {
    tasks.matching {
        it.name.startsWith('dex')
    }.each { dx ->
        if (dx.additionalParameters == null) {
            dx.additionalParameters = []
        }
        dx.additionalParameters += '--multi-dex'
        dx.additionalParameters += "--main-dex-list=$projectDir/<filename>".toString()
    }
}
	

注意上面是修改后的Gradle,其中是一個文本文件的文件名,存放在和這個build.gradle腳本同一級的文件目錄下,而不是 項目根目錄??梢园堰@個文本文件起名為multidex.keep,內容如下.實際就是把需要放在Main Dex的類羅列出來.

android/support/multidex/BuildConfig/class
android/support/multidex/MultiDex$V14/class
android/support/multidex/MultiDex$V19/class
android/support/multidex/MultiDex$V4/class
android/support/multidex/MultiDex/class
android/support/multidex/MultiDexApplication/class
android/support/multidex/MultiDexExtractor$1/class
android/support/multidex/MultiDexExtractor/class
android/support/multidex/ZipUtil$CentralDirectory/class
android/support/multidex/ZipUtil/class
	

project.afterEvaluate標簽在特定的project配置完成后運行,而gradle.projectsEvaluated在所有projects配置完成后運行。 注意afterEvaluate需要放在android{}里,不可放外面。

但是最新的as中,會自動判斷依賴關系來分dex,比如以下application中:

public class MyApp extends MultiDexApplication {

    public static MutilTest5 mutilTest5 = new MutilTest5();

    @Override
    public void onCreate() {
        super.onCreate();
    }
}

默認情況下,本來MuitlText5要分到class2.dex里面去,但是因為app里靜態變量需要用到MuitlText5,如果放到class2.dex中會找不到(因為app中靜態變量初始化會在加載主dex文件之前執行),所以會自動放到主dex文件里去
但是如果依靠as自動分析,在你代碼存在反射和native的情況下,也不保證100%正確,如果不正確,還是需要自己配置哪個類放到主dex中

總結

以上是生活随笔為你收集整理的Android分包方案multidex*的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。