Activity和Fragments之間的參數傳遞和內存優化

最近在翻看項目裏面一些老的業務模塊的時候,發現不少Activity裏面建立Fragment的地方都照搬了網上流傳的錯誤的作法,習慣性地在擴展Fragment類中寫一個newInstance(T parmas)的靜態函數,而後在Activity中經過調用該函數建立所需的Fragment實例 並把須要的數據做爲參數從Activity傳入到Fragment中:bash

誠然這使咱們能夠很方便地獲取到Fragment的實例,可是因爲參數使經過靜態函數傳入的,沒法直接賦值給Fragment實例的內部 變量,而是經過setArguments()的方式保存在Fragment類特殊持有的Bundle中,待須要時再將其取出來使用。問題由此引起而來,若是傳遞的參數是幾個基本數據類型或者比較簡單的類,那麼不會產生任何問題,當傳遞的數據量比較大的時候(好比說數量可觀的List)容易產生內存問題。由於Bundle只接受基本數據類型或者已實現了Serializable序列化接口的類型,因此當咱們把數據序列化後 在傳遞進去,實際上序列化自己是一個深拷貝的過程,此時內存中已經產生了數據的一個副本,而不是對該數據的引用,形成了內存的浪費。當一個Activity中包含有不少這樣的Fragment的時候產生的問題更大:

當app轉到後臺以後,fragment狀態變量會經過activity的onSaveInstanceState()函數保存,查看源碼可看到底層經過Parcel進行傳遞,而Parcel的傳遞的大小是有限制的,通常爲1Mb左右,若是超出了限制應用甚至會崩潰掉。因此對於Activity和Fragments之間大數據量的傳遞應該使用淺拷貝的機制,即在內存中應該只存在一個實例,Activity和Fragment只對其進行引用。運用Android Jetpack架構裏面的 ViewModel能夠很容易地實現上面這一點。

public void loadPageDetailFinish(TabListBean pageInfo) {
        PageViewModel model = ViewModelProviders.of(this).get(PageViewModel.class);
        model.setPageInfo(pageInfo);
    }
複製代碼
相關文章
相關標籤/搜索