dex分包之--------multidex包的配置使用

目錄:
  • 一、前言
  • 二、產生原因
  • 三、MultiDex的簡要原理
  • 四、MultiDex的使用

一、前言

首先說一下我遇到的情況,最近接手了一個項目是在已有的項目里進行更新添加一些功能,然后該項目導了N多的包,在我使用Android Studio的run”App”直接安裝到手機上運行是正常的,然后正式打包安裝后就崩潰了,當時覺得很奇怪,然后一看日志:

trouble writing output:?
Too many field references: 131000; max is 65536.?
You may try using --multi-dex option.

很明顯,方法數65536上限了,那為什么直接運行又沒問題呢??

沒辦法只好查資料:?

Note: While using Instant Run, Android Studio automatically configures your app for multidex when your app's minSdkVersion is set to 21 or higher. Because Instant Run only works with the debug version of your app, you still need to configure your release build for multidex to avoid the 64K limit.

大概意思就是:

如果使用Instant Run,當app的minSdkVersion大于或等于21時,Android Studio會自動配置支持multidex,但是僅debug版本有效,release版仍然需要配置multidex來突破64K限制。

原來當android sdk大于21的時候debug自動支持multidex;好了回到正文multidex分包

二、產生原因

在Android系統中,一個App的所有代碼都在一個Dex文件里面。Dex是一個類似Jar的存儲了多有Java編譯字節碼的歸檔文件。因為Android系統使用Dalvik虛擬機,所以需要把使用Java Compiler編譯之后的class文件轉換成Dalvik能夠執行的class文件。這里需要強調的是,Dex和Jar一樣是一個歸檔文件,里面仍然是Java代碼對應的字節碼文件。當Android系統啟動一個應用的時候,有一步是對Dex進行優化,這個過程有一個專門的工具來處理,叫DexOpt。DexOpt的執行過程是在第一次加載Dex文件的時候執行的。這個過程會生成一個ODEX文件,即Optimised Dex。執行ODex的效率會比直接執行Dex文件的效率要高很多。但是在早期的Android系統中,DexOpt有一個問題,也就是這篇文章想要說明并解決的問題。DexOpt會把每一個類的方法id檢索起來,存在一個鏈表結構里面。但是這個鏈表的長度是用一個short類型來保存的,導致了方法id的數目不能夠超過65536個。當一個項目足夠大的時候,顯然這個方法數的上限是不夠的。盡管在新版本的Android系統中,DexOpt修復了這個問題,但是我們仍然需要對低版本的Android系統做兼容。
為了解決方法數超限的問題,需要將該dex文件拆成兩個或多個,為此谷歌官方推出了multidex兼容包,配合AndroidStudio實現了一個APK包含多個dex的功能。

三、MultiDex的簡要原理?

我們以APK中有兩個dex文件為例,第二個dex文件為classes2.dex。?
兼容包在Applicaion實例化之后,會檢查系統版本是否支持 multidex,classes2.dex是否需要安裝。?
如果需要安裝則會從APK中解壓出classes2.dex并將其拷貝到應用的沙盒目錄下。?
通過反射將classes2.dex注入到當前的classloader中。?
下面引入一下官方的文檔:?
https://developer.android.com/tools/building/multidex.html#about

四、MultiDex的使用

1、在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.1’



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

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


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


注冊如下:


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


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



本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/447049.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/447049.shtml
英文地址,請注明出處:http://en.pswp.cn/news/447049.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++ primer第六章函數的學習

介紹 首先介紹函數的定義和聲明,包括如何傳入參數以及函數如何返回結果。C語言允許使用重載函數,即幾個不同的函數可以使用向同一個名字。所以接下來介紹重載函數的方法,以及編譯器選擇如何從函數的若干重載的形式中選取一個與調用模板相互匹…

C語言指針作為函數參數 以及智能指針作為函數參數

總所周知指針作為函數參數傳遞的時候 傳遞的是指針的拷貝&#xff08;指針也是變量&#xff09; 這里提供四種指針的傳遞方法 改到實際的指針。 #include <stdio.h> #include <memory> #include <iostream> using namespace std; void test1(char **string)…

Android Studio打包和引用aar

一、簡介 Android 庫在結構上與 Android 應用模塊相同。它可以提供構建應用所需的一切內容&#xff0c;包括源代碼、資源文件和 Android 清單。不過&#xff0c;Android 庫將編譯到您可以用作 Android 應用模塊依賴項的 Android 歸檔 (AAR) 文件&#xff0c;而不是在設備上運行…

C++ primer第六章6.4函數的學習 之函數的重載

6.4 函數的重載 函數的名字相同但是形參的列表不同&#xff0c;將其稱之為重載函數 void print(const char *cp); void print(const int *beg,const int * end); void print(const int ia[],size_t size); 形如上面所展現的這樣&#xff0c;當調用這些函數的時候&#xff0c;…

C++有限狀態機的實現

//待完善 有限狀態機是一個很常用的技術&#xff0c;在流程控制和游戲AI中都比較實用&#xff0c;因為狀態機編程簡單又很符合直覺。與有限狀態機類似的是設計模式中的狀態模式。本文是參考《Programming Game AI by Example》 一、 記得最開始工作時候也接觸過有限狀態機&…

手勢希爾排序

void shell_sort(int *data, int length){int gap0;int i0,j0;for(gaplength/2;gap>1;gap/2){//組內插入排序for(igap;i<length;i){int temp data[i];for(ji-gap;j>0&&temp<data[j];jj-gap){data[jgap]data[j];}data[jgap]temp;}} }

Android之android.os.Build

一、類概述&#xff1a;從系統屬性中提取設備硬件和版本信息。 二、內部類&#xff1a; 1、Build.VERSION 各種版本字符串 2、Build.VERSION_CODES 目前已知的版本代碼的枚舉類 三、常量&#xff1a;UNKNOWN 當一個版本屬性不知道時所設定的值。其字符串值為 “unknown” 。 …

C++ unsigned char*轉化為string的形式

unsigned char*轉化為string int main(int argc,char **argv){//unsigned char * 轉化為string//參考鏈接 https://www.itdaan.com/tw/4ff531a5e6651468a5b7c6d95927ba3dunsigned char *foo;unsigned char str[] "Hello world";string strHH;foo str;strHH.append…

KMP算法面試題

面試題&#xff1a;寫一個在一個宇符串(n)中尋找一個子串&#xff08;m)第一個位置的函數。 10G的日志中&#xff0c;如何快速地查找關鍵字&#xff1f;

C++對于程序調試很有用的系統自帶的名字

簡單介紹 __func__當前調試的函數的名字__FILE__存放文件名的字符串的字面值__LINE__存放當前行號的整型字面值__TIME__存放文件編譯時間的字符串的字面值__DATE__存放文件編譯日期的字符串的字面值 例子 if(word.size() < threshold){cerr << "Error: " …

Android中List、Set、Map數據結構詳解

Android中一般使用的數據結構有java中的基礎數據結構List&#xff0c;Set&#xff0c;Map。還有一些Android中特有的幾個&#xff0c;SparseArray(使用Map時Key是int類型的時候可以用這個代替)等。 繼承關系&#xff1a; Collection<–List<–ArrayList Collection<…

Android設計模式之——單例模式

一、介紹 單例模式是應用最廣的模式之一&#xff0c;也可能是很多初級工程師唯一會使用的設計模式。在應用這個模式時&#xff0c;單例對象的類必須保證只有一個實例存在。許多時候整個系統只需要擁有一個全局對象&#xff0c;這樣有利于我們協調系統整體的行為。 二、定義 …

我的職業生涯規劃(軟件工程)

以后筆記先在語雀整理 方便一點https://www.yuque.com/juhao-pqdor/goeie3 整理一下自己的筆記 彌補一下以前沒寫博客的遺憾吧 二十載求學路將盡&#xff0c;行文至此&#xff0c;思緒萬千。求學之路始于家鄉&#xff0c;竿轉熱河&#xff0c;而今終于石門。一路行之如人飲水…

C++ primer第六章6.5函數的學習 之特殊用途的語言特性

6.5.1 默認實參 將反復出現的數值稱為函數的默認實參&#xff0c;調用含有默認實參的時候可以包含該實參也可以不包含比如程序打開頁面會有一個默認的寬高&#xff0c;如果用戶不喜歡也允許用戶自由指定與默認數值不同的數值&#xff0c;具體例子如下圖所示 typedef string::s…

Android設計模式之——Builder模式

一、介紹 Builder模式是一步一步創建一個復雜對象的創建型模式&#xff0c;它允許用戶在不知道內部構建細節的情況下&#xff0c;可以更精細的控制對象的構造流程。該模式是為了將構建復雜對象的過程和它的部件解耦&#xff0c;使得構建過程和部件的表示隔離開來。 因為一個復…

c++后端開發書籍推薦

推薦書籍: 略讀80% 精讀50% C&#xff1a; C Primer Plus C和指針&#xff08;入門書 不只是指針&#xff09; C陷阱與缺陷&#xff08;宏相關&#xff09; C專家編程 C&#xff1a; 有專門的視頻 C primer C程序設計原理與實踐&#xff08;c之父寫的 入門經典&#xff09; Ef…

C++ primer第六章6.6函數匹配

函數的匹配 當重載函數的形參數量相等以及某些形參的類型可以由其他的類型轉化得來的時候&#xff0c;對于函數的匹配就會變得很難 確定候選函數和可行函數 函數匹配的第一步就是選定本次調用對應的重載函數集&#xff0c;集合中的函數稱為候選函數。候選函數具有兩個特征&am…

Android設計模式之——原型模式

一、介紹 原型模式是一個創建型的模式。原型二字表明了該模型應該有一個樣板實例&#xff0c;用戶從這個樣板對象中復制出一個內部屬性一致的對象&#xff0c;這個過程也就是我們俗稱的“克隆”。被復制的實例就是我們所稱的“原型”&#xff0c;這個原型也是可定制的。原型模…

C++ primer第六章6.7函數指針

函數指針 函數指針指向的是函數而不是對象。和其他指針一樣&#xff0c;函數指針指向某種特定的類型。函數的類型由他的返回類型和形參類型共同決定&#xff0c;而與函數的名字無關。 //比較兩個string對象的長度 bool lengthCompare(const string &,const string &);…

Android設計模式之——工廠方法模式

一、介紹 工廠方法模式&#xff08;Factory Pattern&#xff09;&#xff0c;是創建型設計模式之一。工廠方法模式是一種結構簡單的模式&#xff0c;其在我們平時開發中應用很廣泛&#xff0c;也許你并不知道&#xff0c;但是你已經使用了無數次該模式了&#xff0c;如Android…