Android中Activity頻繁進入再退出時程式崩潰的解決方案
最近在對一款開發中的遊戲進行壓力測試時會出現崩潰的問題,具體場景是 在進入一個Activity時立即按返回鍵退出該Activity再迅速進入該Activity,進入退出的時間間隔越短越容易發生崩潰,後來列印日誌發現,由於Activity進入需要載入資源,退出需要釋放資源,這兩個操作都需要一定的時間,照以上場景進行壓力測試就會出現 Activity在資源還沒載入完之前然後程式就會去釋放資源,這樣就會出現空指標而崩潰;另一種情況是程式載入資源比較多,這樣耗費的時間會比較久,同樣釋放資源也會比較久,在立即退出Activity再迅速進入該Activity的時候就會出現Activity的資源還沒來得及釋放,然後就再次載入了一遍資源,這樣就會出現記憶體溢位異常。
解決問題一定要從根源出發,這樣才能確保問題被徹底解決。上述問題的根源就是 由於使用者操作太快導致資源在未被載入完之前又開始釋放,以及資源會被重複載入兩次。從問題根源出發,我們只要保證資源在載入完成之前確保資源不會被釋放,以及資源不會被重複載入,這樣問題就可以迎刃而解了。
解決方案有兩種:一是加Loading頁面,強制使用者等待,這種方式在很多比較大型的遊戲裡很常見。二,是設定標誌位在Activity資源載入完成之前禁止使用者退出Activity, 這個適用於一些資源不太多,沒有Loading頁面的的情況,本質上也是強制使用者等待(一些小的遊戲常常沒有loading頁面 ,資源載入也載入也比較快,所以常常忽略了壓力測試)
第一種方案,相信做遊戲的朋友們都很熟悉,這裡就不細講了。
第二中方案,這裡給出個一個框架,如下:
public class Test1 extends Activity
{
public static final int MSG_INIT_COMPLETE = 1;
public static final int MSG_DELAYED = 200;
private boolean isResume;
@Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
initRes();
isResume = false;
mHandler.sendEmptyMessageDelayed(MSG_INIT_COMPLETE, MSG_DELAYED);
}
public Handler mHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what)
{
case MSG_INIT_COMPLETE:
isResume = true;
break;
}
}
};
protected void onDestroy()
{
// TODO Auto-generated method stub
super.onDestroy();
recycleRes();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
// TODO Auto-generated method stub
if (keyCode == KeyEvent.KEYCODE_BACK)
{
if (isResume)
{
startActivity(new Intent(this,Test2.class));
finish();
}
else
return false;
}
return super.onKeyDown(keyCode, event);
}
}
以上程式碼框架是防止Test1的資源被載入完成之前開始釋放資源,即在資源載入完成之前遮蔽返回鍵事件。為了保險起見,在不影響使用者體驗的前提下大家可以把MSG_DELAYED的值再設定的大些。
public class Test extends Activity implements OnClickListener
{
public static final int MSG_INIT_COMPLETE = 1;
public static final int MSG_DELAYED = 200;
private boolean isResume;
@Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
isResume = false;
mHandler.sendEmptyMessageDelayed(MSG_INIT_COMPLETE, MSG_DELAYED);
}
public Handler mHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what)
{
case MSG_INIT_COMPLETE:
isResume = true;
break;
}
}
};
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
case TAG_GOTO_TEST1:
if(isResume)
{
startActivity(this,test1.class);
finish();
}
break;
}
}
解決問題一定要從根源出發,這樣才能確保問題被徹底解決。上述問題的根源就是 由於使用者操作太快導致資源在未被載入完之前又開始釋放,以及資源會被重複載入兩次。從問題根源出發,我們只要保證資源在載入完成之前確保資源不會被釋放,以及資源不會被重複載入,這樣問題就可以迎刃而解了。
解決方案有兩種:一是加Loading頁面,強制使用者等待,這種方式在很多比較大型的遊戲裡很常見。二,是設定標誌位在Activity資源載入完成之前禁止使用者退出Activity, 這個適用於一些資源不太多,沒有Loading頁面的的情況,本質上也是強制使用者等待(一些小的遊戲常常沒有loading頁面 ,資源載入也載入也比較快,所以常常忽略了壓力測試)
第一種方案,相信做遊戲的朋友們都很熟悉,這裡就不細講了。
第二中方案,這裡給出個一個框架,如下:
public class Test1 extends Activity
{
public static final int MSG_INIT_COMPLETE = 1;
public static final int MSG_DELAYED = 200;
private boolean isResume;
@Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
initRes();
isResume = false;
mHandler.sendEmptyMessageDelayed(MSG_INIT_COMPLETE, MSG_DELAYED);
}
public Handler mHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what)
{
case MSG_INIT_COMPLETE:
isResume = true;
break;
}
}
};
protected void onDestroy()
{
// TODO Auto-generated method stub
super.onDestroy();
recycleRes();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
// TODO Auto-generated method stub
if (keyCode == KeyEvent.KEYCODE_BACK)
{
if (isResume)
{
startActivity(new Intent(this,Test2.class));
finish();
}
else
return false;
}
return super.onKeyDown(keyCode, event);
}
}
以上程式碼框架是防止Test1的資源被載入完成之前開始釋放資源,即在資源載入完成之前遮蔽返回鍵事件。為了保險起見,在不影響使用者體驗的前提下大家可以把MSG_DELAYED的值再設定的大些。
public class Test extends Activity implements OnClickListener
{
public static final int MSG_INIT_COMPLETE = 1;
public static final int MSG_DELAYED = 200;
private boolean isResume;
@Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
isResume = false;
mHandler.sendEmptyMessageDelayed(MSG_INIT_COMPLETE, MSG_DELAYED);
}
public Handler mHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what)
{
case MSG_INIT_COMPLETE:
isResume = true;
break;
}
}
};
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
case TAG_GOTO_TEST1:
if(isResume)
{
startActivity(this,test1.class);
finish();
}
break;
}
}
這段程式碼是防止Test1的資源在釋放完之前再次進入Test1造成記憶體溢位,同樣,在不影響使用者體驗的前提下進入Test1的延遲時間可以再長久一些。
-------------------------------------------------------------------------------------
本文出自http://labs.easymobi.cn/?p=4386
相關文章
- Android7.1.1Toast崩潰解決方案AndroidAST
- Win10系統執行迅雷軟體頻繁崩潰的解決方法Win10
- android Activity崩潰日誌收集Android
- Android頻繁播放簡短音訊解決方案---SoundPoolAndroid音訊
- 【Azure Cloud Services】雲服務頻繁發生伺服器崩潰的排查方案Cloud伺服器
- Android 退出多個Activity | 退出程式Android
- Android 12 “致命”崩潰解決之路Android
- 記錄一次解決App崩潰問題的解決方案APP
- 解決PythonWin執行時崩潰的辦法Python
- Node出錯導致執行崩潰的解決方案
- win10系統下資源管理器頻繁崩潰重啟如何解決Win10
- Android Service入門到崩潰Android
- GOLANG空指標崩潰時堆疊消失和解決方案Golang指標
- 多維分析模型頻繁變動的解決方案有哪些?模型
- win10 pr崩潰怎麼解決_win10 pr崩潰解決辦法Win10
- CrashSight異常崩潰管理解決方案
- Android中處理崩潰異常Android
- 絕地求生崩潰怎麼解決win10_win10絕地求生崩潰的解決方法Win10
- C++記錄程式崩潰時的dumpfileC++
- Android進階;App的異常崩潰處理AndroidAPP
- Android 收集程式崩潰異常資訊Android
- Android退出多個ActivityAndroid
- WkWebView 令人崩潰的崩潰WebView
- [解決] Goland 開啟後直接崩潰GoLand
- Hbase master gone 系統崩潰. 遭遇 hbase bug 以及對應的解決方案.ASTGo
- Source Insight崩潰的解決辦法
- Android 如何收集已釋出程式的崩潰資訊Android
- 解決Kafka消費者啟動時頻繁列印日誌Kafka
- 解決Qt中ui->tableView->setModel(model);導致程式崩潰 問題QTUIView
- windows7 頻繁當機的解決方法Windows
- 全面解決amule容易崩潰和中文顯示、輸入的問題(轉)
- activity的退出功能
- 移動APP崩潰捕獲解決方案CrashSight之常用術語解釋(上)APP
- 移動APP崩潰捕獲解決方案CrashSight之常用術語解釋(下)APP
- 使用代理IP時頻繁掉線如何解決?
- 分享:MySQL資料庫崩潰解決過程MySql資料庫
- win10輸入法lol崩潰怎麼修復_win10輸入法lol崩潰如何解決Win10
- 微軟釋出win10累積更新導致Microsoft Visio卡死或崩潰臨時解決方案微軟Win10ROS