不要經過Application Object或者其餘全局靜態變量來存放數據數據庫
轉載請註明來自:http://blog.csdn.net/liaoqianchuan00/article/details/24399093app
翻譯自:http://www.developerphil.com/dont-store-data-in-the-application-object/this
在咱們的應用程序中,不少地方可能用到同一個數據。不少時候咱們可能不想經過Intent在Activity之間傳遞或者持久化的存放這些數據來。spa
咱們可能會將這些數據存放在Application對象中,這樣咱們就能夠在全部的Activity中訪問了。這個方法很簡單,可是其實是徹底錯誤的。.net
你的程序可能會由於NullPointerException而crash掉,由於上面的方案是基於你假設你存放的數據一直都在那裏的。翻譯
Application對象:對象
// access modifiers omitted for brevityblog
class MyApplication extends Application {進程
String name;內存
String getName() {
returnname;
}
void setName(String name) {
this.name= name;
}
}
在第一個Activity中,咱們將一個用戶的名字存放在Application中:
// access modifiers omitted for brevity
class WhatIsYourNameActivity extends Activity {
void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.writing);
//Just assume that in the real app we would really ask it!
MyApplicationapp = (MyApplication) getApplication();
app.setName("DeveloperPhil");
startActivity(newIntent(this, GreetLoudlyActivity.class));
}
}
在第二個Activity中,咱們取出這個用戶的名字:
// access modifiers omitted for brevity
class GreetLoudlyActivity extends Activity {
TextView textview;
void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.reading);
textview= (TextView) findViewById(R.id.message);
}
void onResume() {
super.onResume();
MyApplicationapp = (MyApplication) getApplication();
textview.setText("HELLO" + app.getName().toUpperCase());
}
}
1. 用戶打開程序。
2. 在WhatIsYourNameActivity中,你詢問用戶的名字,而且把它存放到Application中。
3. 在GreetLoudlyActivity中,你從MyApplication對象中取出用戶的名字而且顯示。
4. 用戶按Home鍵離開咱們的應用程序。
5. 數小時後,Android系統可能殺掉你的程序來得到更多的內存。
到如今爲止,看起來都很正常。可是Crash立刻就要發生了。
6. 用戶從新打開程序。
7. Android創建一個新的MyApplication實例,而且從新恢復GreetLoudlyActivity。
8. GreetLoudlyActivity取得用戶的名字,可是如今已是null了,而後報錯NullPointerException。
在這個例子中,由於Application實例是從新建立的,因此name變量是null,致使咱們在調用String->toUpperCase的時候報NullPointerException。
這就將咱們引向了核心問題:Application對象不會一直在內存中存在,他可能被殺掉。和咱們認爲的相反,他不會恢復之前的信息。Android會建立一個新的Application對象,而後從新打開以前用戶按Home離開的那個Activity。
這就是說,若是你假設Activity B不可能在Activity A以前開啓,因此你保存數據在Application中,那麼你的程序可能就會crash。
1. 經過Intent在Activity之間傳遞數據。
2. 使用多種持久化保存數據的方式(文件,數據庫,sharedpreference等)。
3. 作null判斷,而且手動處理null的狀況。
1. 按Home鍵離開你的應用程序
2. 打開DDMS,選中你應用程序的進程,點擊「stop process」。
3. 使用task switcher返回你的應用程序。如今你的應用程序的Application對象就是一個新的實例了。
在Application對象中保存數據室錯誤的而且可能致使你的程序crash,使用Intent來傳遞數據或者將數據保存在disk上。
同時記住,這個問題一樣適用於任何單例或者公共的靜態變量。
備註: 在實際項目中卻仍是使用到了單例和靜態變量, 因此可能致使後臺很長時間以後崩潰, 如今的解決方案是
保存在Activity的成員變量 應該用 onsave存起來 單例 應該在i()中進行一次初始化
或者在 oncreate 從新初始化.