[Android] 疑難雜症-如何避免Activity在Device orientation改變時restart

一、問題描述:

前陣子寫個簡單的Activity,它負責顯示一個含有URL Image的Custom ListView,並把它發佈至Android Pad上測試,在嘗試改變其orientation時,發現Activity會發生重新載入的狀況,導致每改變一次Orientation,ListView就會重新載入資料一次,產生不好的使用者體驗。


二、問題癥結:

Android為了讓應用程式可以在針對Runtime Device Configuration改變,而重新載入相對應的Resource,例如:使用者在程式執行期間更改了語系設定,透過這項機制可以讓程式自動載入相對應的語系設定檔(前提是你有提供alternative resource)。因此預設當某些特定Configuration改變時(Screen Orientation、Locale、External Keyboard...等,詳細請見Configurations),目前正在執行的Activity會進行restart的動作,讓系統可以動態的進行調整。Activity在被Destroy之前會先呼叫onSaveInstanceState(),你可以在程式被重新啟動之前記錄目前的程式狀態,好讓Activity之後藉由onCreate()或onRestoreInstanceState()來載入之前的程式狀態,由於此項機制,所以才會使Activity裡的ListView不斷重新載入。

三、解決方法:更改android:configChanges設定

Android預設會讓Activity在Device Configuration改變時restart,要避免系統自動Restart Activity,必須更改AndroidManifest.xml裡的設定:

1、在AndroidManifest.xml裡找到欲設定的Activity tag。
2、新增該Activity的一項Attribute→android:configChanges,並加入你要取消自動restart的Configuration(參考官方文件),當設定此屬性意昧著系統將不會自動restart,反而會讓程式繼續執行,並呼叫onConfigurationChanged(),讓程式設計者自己處理configuration改變時系統的調整,當然如果程式不需要針對Configuration進行調整,你也可以選擇不實作onConfigurationChanged()方法。例如,Activity-Test不要針對Orientation改變時restart,就可以進行以下設定:

以上此種作法僅適用於Activity在Configuration改變時完全不需要更新,Android官方稱此種作法為「Last Resort」,非需要應該儘量避免這樣子的作法,主要原因在於每個程式應該有完善的Restart機制,即使Configuration Change不需要作出改變,但是只要發生突發事件(例如:電話),使用者必須在接完電話後回到應用程式,如果回來後發現花了五分鐘填的表單必須重填,相信這不是個好的使用體驗。

留言

這個網誌中的熱門文章

[Android] layout_weight的妙用-讓View的大小以百分比率顯示(proportionate size)

[Android] 內部儲存體(Internal Storage)的檔案系統讀寫(File I/O)

【海外婚紗】造型篇-我的超人新祕Sunny-Yang