這幾天碰到一個(gè)顯示bug,Activity A頁(yè)面中的一個(gè)部分本來(lái)是沒(méi)有數(shù)據(jù)不應(yīng)該顯示出來(lái)的,但是卻顯示出來(lái)了。
查看代碼,發(fā)現(xiàn)這個(gè)部分是屬于fragment B的。如果沒(méi)有數(shù)據(jù),B的根布局會(huì)被setVisibilty(gone),但是最終顯示效果卻是B被顯示出來(lái)了,這就很詭異了。于是我對(duì)B的根布局(一個(gè)自定義view)的setVisibilty方法打上斷點(diǎn),發(fā)現(xiàn)B被fragmentmanager 調(diào)用了getView().setVisibilty(Visible),而B(niǎo)的getView()就是其根布局,終于真相大白了。
那問(wèn)題來(lái)了,相關(guān)代碼已經(jīng)一兩年沒(méi)有動(dòng) 了,為什么現(xiàn)在出問(wèn)題了?通過(guò)debug,發(fā)現(xiàn)debug走的fragment版本是25.1.0,但項(xiàng)目引入的fragment的版本明明是24.2.0。懷疑是和fragment的版本有關(guān),于是調(diào)用gradlew:app:dependencies命令,查看項(xiàng)目的依賴,發(fā)現(xiàn)最近有個(gè)新引入的庫(kù),其依賴了support-v4,而且版本是25.1.0。于是嘗試exclude support庫(kù)
compile("依賴") {
exclude group: "com.android.support"
}
再次打包運(yùn)行,發(fā)現(xiàn)問(wèn)題解決了。看來(lái)確實(shí)是25.1.0版本的fragment 出了問(wèn)題。對(duì)比下代碼,發(fā)現(xiàn)確實(shí)24.2.0版本和25.1.0版本的framgnet內(nèi)部實(shí)現(xiàn)有了不少變化,v25.1.0多了一個(gè)FragmentTransition類,在此類中多次調(diào)用fragment.getView().setVisibility()。
所以:
- 控制fragment的顯示/隱藏,最好還是通過(guò)fragmentmanager去操作,不要通過(guò)控制fragment的根布局的vibibilty去操作。
- 接入新的依賴時(shí)注意其引入的間接依賴,避免依賴沖突產(chǎn)生的依賴版本提升
將support庫(kù)升級(jí)到25.3.1版本后又發(fā)現(xiàn)fragmentmanager內(nèi)部沒(méi)有再調(diào)用fragment.getView().setVisibility()了,所以直接設(shè)置fragment根布局的Visibilty也就沒(méi)有問(wèn)題了。
但我覺(jué)得,最好還是不要這么做,畢竟support庫(kù)的framgnet實(shí)現(xiàn)經(jīng)常變,說(shuō)不定哪天又出問(wèn)題了。而且fragment畢竟不是view,要控制顯示/隱藏,還是通過(guò)framgent的方式去做,不能像View那樣直接setVisibilty.
另外,接入第三方lib是不可避免的事,怎么能避免依賴版本沖突帶來(lái)的影響呢?這里有兩種解決版本:
- 添加依賴時(shí)exclude已有的依賴,如上文的
exclude group: "com.android.support"這樣 - 在集成打包的module中,指定某個(gè)依賴的版本如:
compile("com.android.support:support-v4:24.2.0") {
force = true
}
這樣的話,即使其他間接依賴引入了版本高于24.2.0的v4包(如25.1.0),在打包時(shí)最終集成進(jìn)去的也會(huì)是24.2.0版本的v4包