2011-03-15 259 views
11

我有一個非常簡單的android應用程序,只顯示一個空白的白屏。當我通過按HOME按鈕關閉應用程序時,然後嘗試再次打開應用程序,它崩潰,我得到「強制關閉」按鈕。在Eclipse中,我收到了這個錯誤,「ActivityManager:警告:活動未啓動,因爲當前活動正在爲用戶保留。」。我如何解決這個崩潰?Android應用程序關閉並重新打開時崩潰

public class HelloAndroid extends Activity { 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, 
          WindowManager.LayoutParams.FLAG_FULLSCREEN); 

    setContentView(new Panel(this)); 
} 

class Panel extends SurfaceView implements SurfaceHolder.Callback { 

    private TutorialThread _thread; 

    public Panel(Context context) { 
     super(context); 

     // register our interest in hearing about changes to our surface 
     SurfaceHolder holder = getHolder(); 
     holder.addCallback(this); 
     _thread = new TutorialThread(holder, this); 

     setFocusable(true); 
    } 

    @Override 
    public void onDraw(Canvas canvas) { 

     // Clear the background 
     canvas.drawColor(Color.WHITE); 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
     // resize canvas here 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     _thread.setRunning(true); 
     _thread.start(); 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     // simply copied from sample application LunarLander: 
     // we have to tell thread to shut down & wait for it to finish, or else 
     // it might touch the Surface after we return and explode 
     boolean retry = true; 
     _thread.setRunning(false); 
     while (retry) { 
      try { 
       _thread.join(); 
       retry = false; 
      } catch (InterruptedException e) { 
       // we will try it again and again... 
      } 
     } 
    } 
} 

class TutorialThread extends Thread { 
    private SurfaceHolder _surfaceHolder; 
    private Panel _panel; 
    private boolean _run = false; 

    public TutorialThread(SurfaceHolder surfaceHolder, Panel panel) { 
     _surfaceHolder = surfaceHolder; 
     _panel = panel; 
    } 

    public void setRunning(boolean run) { 
     _run = run; 
    } 

    @Override 
    public void run() { 
     Canvas c; 
     while (_run) { 
      c = null; 
      try { 
       c = _surfaceHolder.lockCanvas(null); 
       synchronized (_surfaceHolder) { 
        _panel.onDraw(c); 
       } 
      } finally { 
       // do this in a finally so that if an exception is thrown 
       // during the above, we don't leave the Surface in an 
       // inconsistent state 
       if (c != null) { 
        _surfaceHolder.unlockCanvasAndPost(c); 
       } 
      } 
     } 
    } 
} 

}

添加logcat的

03-15 15:36:05.579: INFO/AndroidRuntime(4441): NOTE: attach of thread 'Binder Thread #2' failed 
03-15 15:36:05.719: DEBUG/AndroidRuntime(4449): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<< 
03-15 15:36:05.719: DEBUG/AndroidRuntime(4449): CheckJNI is OFF 
03-15 15:36:05.719: DEBUG/dalvikvm(4449): creating instr width table 
03-15 15:36:05.759: DEBUG/AndroidRuntime(4449): --- registering native functions --- 
03-15 15:36:05.969: INFO/ActivityManager(1294): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.example.helloandroid/.HelloAndroid } 
03-15 15:36:05.979: DEBUG/Launcher(1371): onPause+ 
03-15 15:36:05.979: DEBUG/Launcher.DragController(1371): +endDrag: false 
03-15 15:36:05.979: DEBUG/Launcher.DragController(1371): mDragging == false 
03-15 15:36:05.979: DEBUG/Launcher.DragController(1371): -endDrag: false 
03-15 15:36:05.979: DEBUG/Launcher(1371): onPause- 
03-15 15:36:05.999: DEBUG/AndroidRuntime(4428): Shutting down VM 
03-15 15:36:05.999: DEBUG/AndroidRuntime(4449): Shutting down VM 
03-15 15:36:05.999: WARN/dalvikvm(4428): threadid=1: thread exiting with uncaught exception (group=0x4001d7e0) 
03-15 15:36:06.009: DEBUG/dalvikvm(4449): Debugger has detached; object registry had 1 entries 
03-15 15:36:06.009: INFO/AndroidRuntime(4449): NOTE: attach of thread 'Binder Thread #3' failed 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): FATAL EXCEPTION: main 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): java.lang.IllegalThreadStateException: Thread already started. 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at java.lang.Thread.start(Thread.java:1322) 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at com.example.helloandroid.HelloAndroid$Panel.surfaceCreated(HelloAndroid.java:55) 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at android.view.SurfaceView.updateWindow(SurfaceView.java:538) 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:206) 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at android.view.View.dispatchWindowVisibilityChanged(View.java:3888) 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:725) 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:725) 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at android.view.ViewRoot.performTraversals(ViewRoot.java:748) 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1737) 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at android.os.Handler.dispatchMessage(Handler.java:99) 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at android.os.Looper.loop(Looper.java:123) 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at java.lang.reflect.Method.invokeNative(Native Method) 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at java.lang.reflect.Method.invoke(Method.java:521) 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
03-15 15:36:06.029: ERROR/AndroidRuntime(4428):  at dalvik.system.NativeStart.main(Native Method) 
03-15 15:36:06.039: WARN/ActivityManager(1294): Force finishing activity com.example.helloandroid/.HelloAndroid 
03-15 15:36:06.541: WARN/ActivityManager(1294): Activity pause timeout for HistoryRecord{450300c0 com.example.helloandroid/.HelloAndroid} 
03-15 15:36:06.549: DEBUG/Launcher(1371): onResume+ 
03-15 15:36:06.549: DEBUG/Launcher.DragController(1371): +endDrag: false 
03-15 15:36:06.549: DEBUG/Launcher.DragController(1371): mDragging == false 
03-15 15:36:06.549: DEBUG/Launcher.DragController(1371): -endDrag: false 
03-15 15:36:06.549: DEBUG/Launcher(1371): onResume- 
03-15 15:36:08.645: ERROR/KINETO(1370): KLOG0C3- xmk_QueryOSQueue SDL Queue empty : WAIT_FOREVER 
+1

請寄出logcat。 – EboMike 2011-03-15 22:31:11

+0

是的,錯誤是由你的'Thread'引起的。請看下面的答案。 – Wroclai 2011-03-15 22:46:27

+1

LunarLander和JetBoy在經過HOME之後都會崩潰並重新啓動! – Lumis 2011-03-15 23:01:52

回答

19

我已經回答了這樣here的問題。

您遇到的錯誤可能是由您的Thread引起的(沒有看到完整的Logcat,但很難說)。您每次啓動表面已創建,這會使您的應用程序崩潰,因爲您無法兩次調用Thread.start()。看看我上面的鏈接,以更深入地描述問題以及如何解決問題。

因爲我的解釋是不夠的,我將發佈整個解決方案:

內,您的Runnable/Thread

private Object mPauseLock = new Object(); 
private boolean mPaused; 

// Constructor stuff.  

// This should be after your drawing/update code inside your thread's run() code. 
synchronized (mPauseLock) { 
    while (mPaused) { 
     try { 
      mPauseLock.wait(); 
     } catch (InterruptedException e) { 
     } 
    } 
} 

// Two methods for your Runnable/Thread class to manage the thread properly. 
public void onPause() { 
    synchronized (mPauseLock) { 
     mPaused = true; 
    } 
} 

public void onResume() { 
    synchronized (mPauseLock) { 
     mPaused = false; 
     mPauseLock.notifyAll(); 
    } 
} 

在你SurfaceView類:

private boolean mGameIsRunning; 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    // Your own start method. 
    start(); 
} 

public void start() { 
    if (!mGameIsRunning) { 
     thread.start(); 
     mGameIsRunning = true; 
    } else { 
     thread.onResume(); 
    } 
} 
+0

謝謝Viktor,我會研究這個。 – Chris 2011-03-15 22:53:59

+0

感謝Viktor,該代碼工作得很好。 – Chris 2011-03-16 17:05:13

+0

Viktor我不能讓你的代碼與問題中的線程一起工作。 On surfaceDestroyed調用關閉線程並在用戶每次離開此活動時運行,其中包括按Home按鈕時的情況。 – Lumis 2011-03-17 09:42:02

2

這裏有一個簡單的解決方案這在某些情況下可能是可以接受的,比如背景動畫屏幕和狀態不需要恢復的活動 - 表面vi新聞活動需要暫停時完成。

protected void onPause() { 
super.onPause(); 
finish(); 
} 

更好的解決方案是從構造移動線程的創建插入surfaceCretaed這樣的:

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    _thread = new TutorialThread(holder, this); 
    _thread.setRunning(true); 
    _thread.start(); 
} 

然後在線程循環創建一個暫停標記:

if(!pause){ 
    _panel.onDraw(c); 
} 

終於在onPause和onRestore中爲活動設置了暫停標誌:

protected void onResume() { 
      super.onResume(); 
      pause = false;  
     } 

     protected void onPause() { 
      super.onPause(); 
      pause = true; 
     } 

當用戶單擊主頁按鈕surfaceDestroyed被調用將關閉當前線程「_thread」。當他返回到應用程序時,surfaceCreated會將引用「_thread」分配給新線程,而舊線程對象將被垃圾收集器刪除。

+1

這不是一個正確的方法來處理它 – Wroclai 2011-03-16 09:56:56

+1

如果你知道爲什麼不編輯問題中的代碼以使其正常工作,否則它就是所有的理論......當我想出一個工作代碼時,我會發布它 – Lumis 2011-03-16 10:25:54

+0

@Lumis:看到我的答案和那裏的鏈接。有一個解決方案,你必須正確管理線程,使用'synchronized'和鎖。 – Wroclai 2011-03-16 10:28:38

3

對以下解決方案進行了測試。代碼檢查線程狀態,如果終止則創建一個新狀態。 沒有崩潰,我能看到的唯一的問題是遊戲狀態沒有保存,所以基本上從HOME鍵按回來,再次開始遊戲。 p.s.記得從Lunarview視圖中傳遞上下文並設置爲mContextLunarView。 希望這有助於。這些論壇真棒。保持。

public void surfaceCreated(SurfaceHolder holder) { 
    // start the thread here so that we don't busy-wait in run() 
    // waiting for the surface to be created  

    if(thread.getState() == Thread.State.TERMINATED) { 
     //LunarView Thread state TERMINATED..make new...under CheckCreateThread 

     thread = new LunarThread(holder, mContextLunarView, new Handler() { 
      @Override 
      public void handleMessage(Message m) { 
       mStatusText.setVisibility(m.getData().getInt("viz")); 
       mStatusText.setText(m.getData().getString("text")); 
      } 
     });  
    } 

    thread.setRunning(true); 
    thread.start(); 
} 
+0

工作正常!非常感謝! – 2012-06-14 15:22:55

相關問題