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