天天看點

【譯】用Fragment解決螢幕旋轉(狀态發生變化)狀态不能保持的問題

這篇文章解決了在StackOverflow上一個經常被提到的問題。

在配置發生變化(Configuration changs)時,什麼是最好的儲存活動對象方法,比如運作中的線程,Sockets,AsyncTask。

要回答這個問題,我們要先讨論一些開發者在Activity生命周期中使用長時間背景任務時遇到的共同困難。然後,我們将介紹常見的兩種能解決問題但有不好的方法。最後,我們會用一個示例代碼說明推薦的解決方案,它用retained fragment來達到我們的目标。

配置發生變化以及銷毀和重新建立穿越了整個Activity的生命周期,并且引出一個問題,那就是這些事件的發生是不可預測并且在任何時候都可能觸發。并發的背景線程隻加劇了這個問題。假設在Activity中啟動了一個AsyncTask,然後使用者馬上旋轉螢幕,這會導緻Activity被銷毀和重新建立。當AsyncTask最後完成它的任務,它會将結果回報到舊的Activity執行個體,完全沒有意識到新的activity已經被建立了。似乎這不是一個問題,新的Activity執行個體又會讓浪費寶貴的資源重新啟動一個背景線程,而不知道舊的AsyncTask已經在運作。由于這些原因,在配置變化的時候我們需要正确、有效地儲存在Activity執行個體的活動對象。

另一個Google不鼓勵使用它的原因是許多開發者錯誤地認為,設定android:configChanges = "orientation"(這隻是舉例說明),會神奇地避免他們的Activity在不可預知的場景中被銷毀和重新建立。其實不是這樣的。有多種原因可能導緻配置發生變化,而不單單是螢幕橫豎屏的變化。将你的手機中的内容顯示在顯示器上,更改預設語言,修改裝置預設的字型縮放,這三個簡單的例子都有可能觸發裝置的配置變化。這些事件會向系統發出信号,銷毀并重建所有正在運作的Activity,在它們下一次resume的時候。是以設定android:configChanges屬性一般不是好的做法。

在Honeycomb釋出前,跨越Activity執行個體傳遞活動對象的推薦方法是重寫onRetainNonConfigurationInstance()和getLastNonConfigurationInstance()方法。使用這種方法,傳遞跨越Activity 執行個體的活動對象僅僅需要在onRetainNonConfigurationInstance()将活動對象傳回,然後在getLastNonConfigurationInstance()中取出。截止API 13,這些方法都已經被棄用,以支援更有效的Fragment的setRetainInstance(boolean)方法。它提供了一個更簡潔,更子產品化的方式在配置變化的時候儲存對象。我們将在下一節讨論以Fragment為基礎的方法。

自從Android3.0推出Fragment。跨越Activity保留活動對象的推薦方法是在一個Retained Fragment中包裝和管理它們。預設情況下,但配置發生變化時,Fragment會随着它們的宿主Activity被建立和銷毀。調用Fragment#setRetaininstance(true)允許我們跳過銷毀和重新建立的周期。訓示系統保留目前的fragment執行個體,即使是在Activity被創新建立的時候。不難想到使用fragment持有像運作中的線程、AsyncTask、Socket等對象将有效地解決上面的問題。

下面代碼示範如何使用fragment在配置發生變化的時候儲存AsyncTask的狀态。這段代碼保證了最新的進度和結果能夠被傳回更目前正在顯示的Activity執行個體,并確定我們不會在配置發生變化的時候丢失AsyncTask的狀态。下面代碼包含兩個類,一個MainActivity...

<a></a>

...和一個 TaskFragment...

在Activity的生命周期(涉及舊、新Activity的銷毀和建立)中同步背景任務的運作狀态可能非常棘手,并且配置發生變化加劇了這一麻煩。幸運的是使用一個retain fragment可以非常輕松地處理這些事件。它隻要始終持有父Activity的引用,即使在父Activity被銷毀和重新建立之後。

【譯】用Fragment解決螢幕旋轉(狀态發生變化)狀态不能保持的問題

<a href="http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html" target="_blank">譯文位址</a>

本文轉自陳哈哈部落格園部落格,原文連結http://www.cnblogs.com/kissazi2/p/4116456.html如需轉載請自行聯系原作者

kissazi2

繼續閱讀