2016-03-06 66 views
0

我在調查活動切換生命週期方面做了一些實驗,發現有一種情況會出現「黑屏」。如果我錯了,請糾正我。在Android中,可能會出現黑屏作爲開關活動

兩項活動一& B.啓動到B從A

03-06 13:04:52.811: I/LOG(32125): pause A begin 
03-06 13:04:53.811: I/LOG(32125): pause A return 
03-06 13:04:53.813: I/LOG(32125): focus A begin 
03-06 13:04:58.813: I/LOG(32125): focus A return 

In the window, shows the view of Activity A. 

03-06 13:04:58.829: I/LOG(32125): create B begin 
03-06 13:04:58.845: I/LOG(32125): create B return 
03-06 13:04:58.846: I/LOG(32125): start B begin 
03-06 13:04:59.847: I/LOG(32125): start B return 

The view of Act A is hide, it is now shown by Activity B, but it's actually a "black screen" rather than the "actual genereated layout" in Activity B 

03-06 13:04:59.847: I/LOG(32125): resume B begin 
03-06 13:05:00.847: I/LOG(32125): resume B return 
03-06 13:05:00.968: I/LOG(32125): focus B begin 
03-06 13:05:05.968: I/LOG(32125): focus B return 

Until this point, the "actual generated layout" of Activity B is shown here. 

03-06 13:05:06.044: I/LOG(32125): A onSaveInstance 
03-06 13:05:06.044: I/LOG(32125): stop A begin 
03-06 13:05:07.044: I/LOG(32125): stop A return 

下面是在我的活動代碼中的& B.我使用了Thread.sleep模擬長期任務。 (也許這不是一個合適的方式使模擬?)

@Override 
protected void onStart() { 
    super.onStart(); 
    Log.i("LOG","start B begin"); 
    try { 
     Thread.sleep(5000,0); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    Log.i("LOG","start B return"); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    Log.i("LOG","resume B begin"); 
    try { 
     Thread.sleep(5000,0); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    Log.i("LOG","resume B return"); 
} 

@Override 
protected void onStop() { 
    super.onStop(); 
    Log.i("LOG","stop B begin"); 
    try { 
     Thread.sleep(3000,0); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    Log.i("LOG","stop B return"); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    Log.i("LOG", "pause B begin"); 
    try { 
     Thread.sleep(3000,0); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    Log.i("LOG","pause B return"); 
} 

@Override 
public void onWindowFocusChanged(boolean hasFocus) { 
    super.onWindowFocusChanged(hasFocus); 
    Log.i("LOG","focus B begin"); 
    try { 
     Thread.sleep(5000,0); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    Log.i("LOG","focus B return"); 
} 

從上面的實驗,我想出了一些結論和設計策略。

  1. 不要在Act B onResume & onFocus上做太多事情,否則用戶會看到「黑屏」。
  2. 接着(1),在Act B「onStart」中執行。最好讓用戶感受到前面的步驟A所示的延遲,而不是看到「黑屏」的延遲。
  3. AsyncTask絕對是解決方案。向用戶顯示視圖是重中之重,之後應用數據。

然而,還有一個場景是這樣的:
圖表應用。用戶可以在Activity中看到「圖表(佈局)」,但最新的數據還沒有被填充,因爲第二個線程仍在提取數據(可能是因爲它太重了)。

此時用戶將看到一個空白圖表。爲了避免這種情況,我們可以在創建Activity之前獲取數據。在前面的活動或應用程序開始時執行此操作。平滑用戶體驗。


有沒有人找到這個「黑屏」的陷阱?還是我錯誤地理解了事情?非常感謝你!

+0

你可以顯示代碼你有什麼活動A和B –

回答

0

你絆倒在與Android基本原則之一:

不要做(太多)在主線程上運行。

主線程是你的UI線程。生命週期回調方法,如onCreate,onStart等都在主/ UI線程上調用。

如果你做了太多工作,最終會出現屏幕凍結和/或黑屏,是的。

但是,這不應影響您創建視圖或填充數據的位置。這就是爲什麼有不同的生命週期方法。例如。 onCreate被調用一次,這就是爲什麼你應該在那裏設置你的佈局。每次用戶切換回您的活動時,都會調用onResume。你應該在那裏恢復動畫。

AsyncTask確實是從主線程加載數據的好主意。如果你想正確地做到這一點,一般還請看LoaderManagerLoader

5秒鐘執行生命週期回調應該是而不是就是這樣。使用在onCreate或其他適當的地方開始的裝載機,並在完成後用數據填寫您的意見。確保您瞭解何時調用每個生命週期回調,因爲多次執行相同的操作(例如onResume)也可能會浪費精力。

0

在上面的所有代碼中添加睡眠將掛起主線程(這是ui線程) - 這可以解釋奇怪的黑屏。如果那裏沒有睡覺怎麼辦?我認爲你仍然可以通過日誌瞭解生命週期,但沒有任何睡眠。我知道你在做一個模擬,但是如果你的實際任務要花費很長時間,那就去探索一下多線程方法吧(關鍵詞:Looper,AsyncTask,Thread,Runnable,Message,Queue,Post,Handlers等等...這是一個複雜的話題)。

相關問題