我遇到了奇怪的行爲和NullPointerException
(有時)用在Activity
一個Singleton
模式。安卓:活動週期和辛格爾頓
清單中(聲明的方向橫向)的活動:
<activity
android:name="com.lux.game.MainActivity"
android:screenOrientation="landscape" />
活動類:
private GameManager.OnEventListener mEventListener = new GameManager.OnEventListener {
@Override
public void onEvent(Event event) {
if (event == Event.PLAYER_SELECTED_PUZZLE) {
// Do something on the UI
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
// If the orientation is landscape, then initialize the Game Manager
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
GameManager.getInstance().init();
// Register an interface to deal with game events
GameManager.getInstance().registerForEvent(mEventListener);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// The activity was destroyed, remove the interface and clear the references
GameManager.getInstance().cleanUp();
}
的GameManager
單:
public class GameManager {
private static GameManager mInstance;
private GameManager() {
}
public static synchronized getInstance() {
if (mInstance == null) {
mInstance = new GameManager();
}
return mInstance;
}
}
正如你所看到的,我使用GameManager
單身人士處理遊戲事件(玩家選擇一張牌,遊戲結束等)。單身在onCreate()
實例如果方向爲橫向和interface
傳遞給單身和它存儲爲類的成員。在活動的onDestroy()
處刪除interface
。
活動的生命週期和原木:
#1 onCreate(), orientation: LANDSCAPE
#2 back button pressed
#3 onDestroy(), orientation: PORTRAIT
一切工作如我所料,直到我開始鎖定/解鎖並按下設備上的HOME按鈕(真正的設備上測試應用程序,不是模擬器)。
活動的生命週期和原木:
#1 onCreate(), orientation: LANDSCAPE
#2 lock phone
#3 onDestroy(), orientation: PORTRAIT
#4 onCreate(), orientation: PORTRAIT
#5 unlock phone
#6 onDestroy(), orientation: PORTRAIT
#7 onCreate(), orientation: LANDSCAPE
onCreate
和onDestroy
被稱爲服務器次(正常行爲,因爲方向變化),但是這並不造成問題,因爲活動的lifecycle
方法被稱爲excpeted的訂單和interface
被刪除,我不會留下任何可能導致內存泄漏的引用。
問題(有時)談到如果上述被獲取調用以不同順序的步驟的表面:和被逆相比
#1 onCreate(), orientation: LANDSCAPE (inst #1)
#2 lock phone
#3 onDestroy(), orientation: PORTRAIT (inst #1)
#4 onCreate(), orientation: PORTRAIT (inst #2)
#5 unlock phone
#6 onCreate(), orientation: LANDSCAPE (inst #3)
#7 onDestroy(), orientation: PORTRAIT (inst #2)
正如你可以看到,步驟先前的步驟。在onDestroy
之前調用onCreate
。此外,我已經添加了一些(中國科學院#N),這表明有多少活動實例越來越創建,這是越來越摧毀。
根據日誌,總共有而我鎖定/解鎖的手機,它越來越創建3個不同的活動實例。這個問題是由最後一步造成的,當第三個活動(inst#3)被創建,並且第二個活動(inst#2)被銷燬時。我使用的是Singleton
(僅1個實例存在於整個應用程序)來處理事件和管理遊戲,在活動的onDestroy
的Singleton
預計,比賽已經結束,它必須刪除對活動的引用。這樣一來,如果事件發生在比賽中NullPointerException
被拋出,因爲Singleton
已清除所有引用。
- 我應該使用不同於Singleton的方法嗎? (如何處理遊戲事件?)
- 我應該使用onSave/onRestore實例嗎? (爲什麼和如何?)
- 我應該onPause/onResume而不是onCreate/onDestroy?
- 出於想法。如果你有什麼好主意,歡迎如何解決這個問題。