徹底弄清support支持庫赫段,以及v4 v7重復依賴問題深究

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

前言

眾所周知android提供了很多Support Library作為api的補充力试,常見的有supprt-v4苏携,v7等毛仪,但我發(fā)現(xiàn)這些支持庫的版本眾多搁嗓,涉及的內(nèi)容也比較龐雜,本文帶大家梳理一下常見的Support Library箱靴,然后文章后半部分對一個報錯問題展開深究腺逛,那就是我們用開源庫時經(jīng)常碰到的v4重復依賴問題: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的設備上完美運行慨绳,但是app在android 2.3的設備就會crash,報找不到ActionBar的錯誤真竖。這很好理解脐雪,因為舊版本上沒有新版本里新增的類。為了避免使用了最新功能開發(fā)的app只能在最新系統(tǒng)的設備上運行的尷尬恢共,官方把新版系統(tǒng)framework中新增加的接口提出來放到了Android Support Library(支持包)中战秋,開發(fā)者在遇到上面的情況時,就可以使用支持包中具有同樣功能的ActionBar類讨韭,這個支持包會打包進App里脂信,這樣使用了新版本系統(tǒng)上功能的App也可以向后兼容以前的老系統(tǒng)版本設備了癣蟋。
使用支持包中的類除了讓我們免于判斷App運行的系統(tǒng)版本外,還可以使App在各個版本保持同樣的用戶體驗狰闪。如在5.0以下系統(tǒng)使用material design疯搅。

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

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

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

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

support-library支持庫

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

Material Design是Android 5.0加入的新功能,但是很多設備依然裝的是Android4.0系統(tǒng)款咖,如果為了Material Design將minSdkVersion設置為 api21顯然不合理的何暮,那為了Android5.0以下的設備可以使用Material Design的效果,就應該使用support-library铐殃,包括之前的Fragment和現(xià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個部分有依賴關系羊异,二是compat庫占了v4庫的一半大小事秀,v4庫的依賴關系圖:


image.png

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

上面說到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包各自對應著特定的功能嘿歌,每一個都可以單獨地被引用掸掏。

v7 app-compat這個包支持對Action Bar接口的設計模式、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

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

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重復依賴深究

下面詳細介紹 很常見的v4庫的重復依賴問題批糟,先拋出兩個問題:

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包的重復依賴問題

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

image.png

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


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

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

image.png

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

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

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

image.png

運行時報錯: dex文件沖突

image.png

當然,如果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. 首先查看當前項目各種庫的依賴情況:

image.png

2. 找到里面版本沖突的依賴庫,然后查找app項目绘盟,開源庫的lib目錄鸠真,刪除對應的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' 
}
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吠卷,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子沦零,更是在濱河造成了極大的恐慌祭隔,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蠢终,死亡現(xiàn)場離奇詭異序攘,居然都是意外死亡,警方通過查閱死者的電腦和手機寻拂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門程奠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人祭钉,你說我怎么就攤上這事瞄沙。” “怎么了慌核?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵距境,是天一觀的道長。 經(jīng)常有香客問我垮卓,道長垫桂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任粟按,我火速辦了婚禮诬滩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘灭将。我一直安慰自己疼鸟,他們只是感情好,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布庙曙。 她就那樣靜靜地躺著空镜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吴攒,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天张抄,我揣著相機與錄音,去河邊找鬼舶斧。 笑死欣鳖,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的茴厉。 我是一名探鬼主播泽台,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼矾缓!你這毒婦竟也來了怀酷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤嗜闻,失蹤者是張志新(化名)和其女友劉穎蜕依,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體琉雳,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡样眠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了翠肘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片檐束。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖束倍,靈堂內(nèi)的尸體忽然破棺而出被丧,到底是詐尸還是另有隱情,我是刑警寧澤绪妹,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布甥桂,位于F島的核電站,受9級特大地震影響邮旷,放射性物質(zhì)發(fā)生泄漏黄选。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一婶肩、第九天 我趴在偏房一處隱蔽的房頂上張望办陷。 院中可真熱鬧,春花似錦狡孔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至植旧,卻和暖如春辱揭,著一層夾襖步出監(jiān)牢的瞬間离唐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工问窃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留亥鬓,地道東北人。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓域庇,卻偏偏與公主長得像嵌戈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子听皿,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349

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