編輯:Android開發實例
我們要了解Android手機開發與桌面開發有一個主要不同之處:通常在一部Android手機裡同時運行著多個應用(app),每個app對應一個系統進程,當系統需要更多的資源(如內存)而空閒資源不足時,Android系統就會選擇殺掉一些“低優先級”的進程以便釋放所需資源。
Android系統是如何確定進程優先級的高低的呢?
當系統資源嚴重不足時,任何一個進程都有可能被殺掉,而當用戶想回到一個已經不存在於內存中的Activity時,系統只得新建一個這樣的Activity對象並調用它的onCreate()方法進行恢復。所以有時出現這種狀況:一個app大部分時間運行很好,偶爾在切換Activity時出現空指針異常導致強制關閉,這多半是在onCreate()方法裡使用了已經被重置為空的對象(例如intent裡的變量)造成的。即使不出現異常,也會造成表單數據丟失等嚴重影響使用體驗的問題。
要解決這類問題,切不可抱“現在手機內存大,進程一般不會被殺掉”這種僥幸心理,而應該以“應用隨時都會被殺掉”的態度來謹慎處理,下面介紹Google建議的方式。
由於Activity隨時可能需要重建,所以我們要做的事情就是在適當的位置將Activity所需數據進行持久化(從ram復制到rom或sd卡),並在onCreate()方法裡利用這些數據恢復現場。
Activity有兩類數據需要進行持久化處理:“文檔類型數據”和“內部狀態類型數據”,前者例如用戶正在編輯的表單,後者如用戶偏好。
一、為了持久化文檔類型的數據,Google建議使用”即時生效”(edit in place)的編輯策略,具體的方式如下:
這種方式可以最大限度避免數據丟失,只要onPause()方法被觸發執行,即使Activity所在進程被系統kill掉也不會造成數據丟失。唯一要注意的是,界面上最好能提供一個“取消”按鈕或菜單,以便讓用戶可以選擇不保存對文檔的更改。
二、為了持久化內部狀態類型的數據,可以在onPause()裡使用Activity#getPreferences(int)方法,這個方法返回SharedPreferences類型的對象,利用它可以記錄用戶對這個Activity的偏好信息。例如一個日歷應用,用戶可以選擇顯示為周視圖或月視圖,這樣的信息作為內部狀態記錄到SharedPreferences對象以後,下次再打開這個Activity時就可以按用戶上次的選擇來顯示日歷了。
以下代碼來自官方文檔,演示了如何持久化並恢復一個Activity的當前顯示模式:
public class CalendarActivity extends Activity { ... static final int DAY_VIEW_MODE = 0; static final int WEEK_VIEW_MODE = 1; private SharedPreferences mPrefs; private int mCurViewMode; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //取回之前持久化的日歷顯示模式 SharedPreferences mPrefs = getSharedPreferences(); mCurViewMode = mPrefs.getInt("view_mode", DAY_VIEW_MODE); } protected void onPause() { super.onPause(); //持久化日歷顯示模式 SharedPreferences.Editor ed = mPrefs.edit(); ed.putInt("view_mode", mCurViewMode); ed.commit(); } }
是有點麻煩,但為了能讓app穩定運行也值了。
有些同學要問了,為什麼是在onPause()裡持久化而不是在onSaveInstanceState()裡?官方文檔有下面一段話簡要解釋了原因,即前者比後者更可靠,因為onSaveInstanceState()不屬於Activity生命周期的一部分。——既然如此,我想不出onSaveInstanceState()還有什麼其他用途了,大家干脆忘了它吧,還有onRestoreInstanceState()。
Note that it is important to save persistent data in onPause() instead of onSaveInstanceState(Bundle) because the latter is not part of the lifecycle callbacks, so will not be called in every situation as described in its documentation.
注1:關於上面這段話,網上存有一些爭議,我個人還是比較傾向在onPause()裡做持久化——既可靠又好記,唯一的缺點是調用次數稍多。
注2:從Android 3.0(HoneyComb)版本開始,Activity進程在被系統殺掉之前,將保證onStop()方法先執行完成,因此如果我們開發的應用只運行在3.0以上,可以把持久化工作放在onStop()裡以減少持久化的次數。
不要抱僥幸心理,你的Activity隨時可能被銷毀。
解決方法:在onPause()裡持久化Activity數據,在onCreate()裡恢復現場。
參考資料:
ActivitySaving Activity state in Android
今天因為要做一個設置開機畫面的功能,主要是讓用戶可以設置自己的開機畫面,應用層需要做讓用戶選擇開機畫面圖片的功能。所以需要做一個簡單的圖片浏覽選擇程序。最後選用G
在android上導入zxing.jar包,總是報錯: Could not find class com.google.zxing.MultiFormatWrit
shimmer開源庫介紹 Shimmer是Fa
本文實例介紹的是Android的Tab控件,Tab控件可以達到分頁的效果,讓一個屏幕的內容盡量豐富,當然也會增加開發的復雜程度,在有必要的時候再使用。Androi