徹底弄清support支持庫,以及v4 v7重復(fù)依賴問題深究

本篇文章已授權(quán)微信公眾號 hongyangAndroid (鴻洋)獨家發(fā)布

前言

眾所周知android提供了很多Support Library作為api的補充,常見的有supprt-v4,v7等,但我發(fā)現(xiàn)這些支持庫的版本眾多,涉及的內(nèi)容也比較龐雜,本文帶大家梳理一下常見的Support Library,然后文章后半部分對一個報錯問題展開深究,那就是我們用開源庫時經(jīng)常碰到的v4重復(fù)依賴問題:DexException Multiple dex files define。

為何提供支持庫

google為啥要弄這么多支持庫,直接放到sdk里面不好么? 參閱官方文檔有下面3個原因:

1.向后兼容
如,我們開的App需要支持的minSdkVersion=9,targetSdkVersion=11,在程序里使用了android 3.0 (API level 11)提供的ActionBar類,使用compileSdkVersion=11成功編譯出apk。在android 3.0的設(shè)備上完美運行,但是app在android 2.3的設(shè)備就會crash,報找不到ActionBar的錯誤。這很好理解,因為舊版本上沒有新版本里新增的類。為了避免使用了最新功能開發(fā)的app只能在最新系統(tǒng)的設(shè)備上運行的尷尬,官方把新版系統(tǒng)framework中新增加的接口提出來放到了Android Support Library(支持包)中,開發(fā)者在遇到上面的情況時,就可以使用支持包中具有同樣功能的ActionBar類,這個支持包會打包進App里,這樣使用了新版本系統(tǒng)上功能的App也可以向后兼容以前的老系統(tǒng)版本設(shè)備了。
使用支持包中的類除了讓我們免于判斷App運行的系統(tǒng)版本外,還可以使App在各個版本保持同樣的用戶體驗。如在5.0以下系統(tǒng)使用material design。

2.提供不適合打包進framework的功能

Android官方對App開發(fā)提供了推薦設(shè)計,希望Android應(yīng)用都有相對一致的交互設(shè)計來減少用戶的使用成本,希望三方App類似系統(tǒng)應(yīng)用從而完美融入到Android生態(tài)系統(tǒng)中。但是這都僅僅是推薦,不要求開發(fā)者一定要這樣,如果有這種需求就可以使用官方支持包提供的這些功能,避免重復(fù)造輪子。如支持包中的DrawerLayout、Snackbar等類都是這種情況。

3.為了支持不同形態(tài)的設(shè)備

通過使用支持包來在不同形態(tài)設(shè)備上提供功能,如手機、電視、可穿戴設(shè)備等。

support-library支持庫

Android 支持庫提供了諸多未內(nèi)置于框架的功能。這些庫提供向后兼容版本的新功能、框架中未包含的實用 UI 元素,以及應(yīng)用可以利用的一系列實用程序。比如

Material Design是Android 5.0加入的新功能,但是很多設(shè)備依然裝的是Android4.0系統(tǒng),如果為了Material Design將minSdkVersion設(shè)置為 api21顯然不合理的,那為了Android5.0以下的設(shè)備可以使用Material Design的效果,就應(yīng)該使用support-library,包括之前的Fragment和現(xiàn)在的權(quán)限檢查,都是這個原理!

目前為止Android Support Library包含的依賴包有:比較常用的是1,2,3

image.png

support-v4

v4名稱是最開始支持api level4的庫,官方在Support Library 24.2.0版本的時候移除了對Android 2.2(API Level 8)及以下版本的支持,所以從Android Support Library 24.2.0開始,V4包支持的最低版本是Android 2.3即API Level 9),并且把v4庫拆分成5個部分,可以在項目中按需要引用,但是必要性不是很大,一是因為這5個部分有依賴關(guān)系,二是compat庫占了v4庫的一半大小,v4庫的依賴關(guān)系圖:


image.png

比如下面這些都是v4包的內(nèi)容:
Fragment:一個專為解決Android碎片化的類,通過它可以讓同一個程序適配不同的屏幕。
NotificationCompat:支持更豐富的通知形式;
LocalBroadcastManager:適合于應(yīng)用內(nèi)的消息傳遞。
ViewPager:一個可以管理子view的viewgroup,用戶可以在各個view之間自由切換,這個在很多應(yīng)用中都有使用到;

上面說到v4是兼容level9之前的版本,那如果我們的compileSdkVersion>9是不是可以不用v4了? 這個不一定的,比如ViewPager這個類只在V4包中才有,在sdk中沒有。

  • 如何使用v4
compile 'com.android.support:support-v4:21.0.3'

同步gradle之后,在ExternalLibrarys右鍵v4選擇:library propertity查看依賴庫的信息:


image.png

可以看到我們依賴的v4包就在sdk的extras目錄:


image.png

這個是我們在androidStudio的SDK Manager中下載的,如果沒有下載gradle同步后會讓你去下載。

support-v7

V7和V4一樣,同樣包含多個依賴包,但和V4不同的是,V7下的多個子包并不是后面拆分開來的,而是最初發(fā)布時就以各個獨立庫的形式發(fā)布的。它是針對Android 2.3(API Level 9)及以上的版本谷歌提供了一系列的support包(和V4包的命名一樣,V7最初支持的最低版本是Android 2.1即API Level 7,所以稱其為V7,同樣在Android Support Library 24.2.0將V7支持的最低版本改為Android 2.3即API Level 9了),這些support包各自對應(yīng)著特定的功能,每一個都可以單獨地被引用。

v7 app-compat這個包支持對Action Bar接口的設(shè)計模式、Material Design接口的實現(xiàn)等,核心類有ActionBar、AppCompatActivity、AppCompatDialog、ShareActionProvider等

  • 如何使用v7
compile 'com.android.support:appcompat-v7:24.2.1'

用這個maven方式配置v7會自動引入v4庫,so不需要再額外引入v4庫了。
gradle中jar依賴語句格式如 compile 'jar文件組(group/命名空間):jar文件名(name):jar文件版本(version)'。所以上面的語句意思是依賴Android支持庫中第24.2.1版的appcompat-v7庫。

Multidex Support Library

當(dāng)你的項目代碼量越來越大的時候,會發(fā)現(xiàn)某一天運行在Android5.0以下的手機莫名崩潰。報錯:某個類class not found,而這個類明明就有啊。。。其實這就是 著名的方法數(shù)超過 64K 的應(yīng)用異常。解決辦法就是這個支持庫。

android {
    defaultConfig {
        ...
        minSdkVersion 15 
        targetSdkVersion 26
        multiDexEnabled true
    }
    ...
}

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

然后在自定義的Application的加入:

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

v4 supportLibrary重復(fù)依賴深究

下面詳細(xì)介紹 很常見的v4庫的重復(fù)依賴問題,先拋出兩個問題:

v7包含v4嗎?

為啥問這個問題,源于我看網(wǎng)上很多文章,介紹v4的時候不假思索地下結(jié)論:v7包含v4!真的是這樣嗎???

我們打開v7的jar包看源碼,其實appcompat-v7包本身是不包含v4的jar包的:

image.png

新建一個工程,加入v7的依賴包:


dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:24.2.1'
}

看下項目目前的依賴包情況:

image.png

果然,項目自動引入了v4下面的所有包,v7包涵v4的意思是:

compile 'com.android.support:appcompat-v7:24.2.1', gradle會自動加入所有v4包的依賴,并且是和v7相同的版本

support庫必須和compileVersion一致嗎?

image.png

不是必須的。只是官方建議保持一致,如果版本不一致仍然可以編譯運行。

v4包的重復(fù)依賴問題

上面已經(jīng)證明依賴v7包會自動引入v4包,那么在項目中同時依賴v4和v7,會出現(xiàn)所謂的重復(fù)依賴編譯報錯嗎?

image.png

可以成功編譯運行安裝,沒有報錯:


:mylibrary:preDebugUnitTestBuild UP-TO-DATE
:mylibrary:prepareDebugUnitTestDependencies
BUILD SUCCESSFUL
Total time: 7.005 secs

即使同時引入不同版本的v4包,也并沒有出現(xiàn)包依賴重復(fù)的報錯,可以正常編譯運行:(注:紅線是版本和compileSdkVersion不一致導(dǎo)致,此處忽略)

image.png

確實引入了不同版本的v4包:

image.png
  • 結(jié)論: 如果都是maven的方式引入v4包,gradle會自動選擇版本較高的,比如這里的21.0.3版本,不會導(dǎo)致沖突。

接下來,試試maven引入21.0.3的v4包,然后本地引入19.1.0的jar包:

image.png

運行時報錯: dex文件沖突

image.png

當(dāng)然,如果lib放入的和maven配置v4包版本21.0.3相同,是可以的。

(Android從support-20.0.0版本開始,v4的jar包全部升級為aar包),解壓工具提取aar里面的classes.jar然后重命名為support-v4-21.0.3.jar放入lib文件夾

image.png
  • 結(jié)論:v4的依賴沖突其實是不同版本v4的沖突,并且是本地lib和maven引入不同版本才會沖突

異常沖突解決辦法

一個項目往往要引入很多開源庫,試圖統(tǒng)一所有moduler的v4版本是不現(xiàn)實的,只能通過exclude 方法過濾某些庫的v4包,保證整個項目只引入一個版本。

1. 首先查看當(dāng)前項目各種庫的依賴情況:

image.png

2. 找到里面版本沖突的依賴庫,然后查找app項目,開源庫的lib目錄,刪除對應(yīng)的jar包改用maven形式引入。

3. 如果你的app必須要使用本地lib引入v4庫,那么就排除開源庫的v4包:


compile('com.facebook.fresco:fresco:0.10.0') {
       exclude module: 'support-v4'
}

如果是源碼形式引入的開源庫:

compile (project(':thirdpart:RecyclerViewAdapterLibrary')){ 
     exclude group: 'com.android.support' 
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內(nèi)容