2012-07-19 111 views
0

我正在做一個android項目。 我有線程在它的問題。我想在主頁按鈕按下時暫停線程,並在返回到應用程序時恢復它。當暫停和恢復線程時沒有更新UI

這是我的代碼:

Handler handler = new Handler() 
{ 
    @Override 
    public void handleMessage(Message msg) 
    { 
     int tempWaktu = (Integer) msg.obj; 

     if(!status){ 
      if(tempWaktu < 10) textSec.setText("0"+tempWaktu); 
      else textSec.setText(""+tempWaktu); 
     } 

     if(tempWaktu==0){ 
      stopYourActivity(); 
     } 
    } 
}; //handler 

@Override 
public void onStart() 
{ 
    super.onStart(); 

    timer = new Thread(new Runnable() { 
     public void run() { 
     try 
     { 
      while(jalan){ 
       if(running){ 
        Thread.sleep(1000); 
        waktu--; 
        Message msg = handler.obtainMessage(1, waktu); 
        handler.sendMessage(msg); 
        if(waktu==0){ 
         running = false; 
        } 
       } 
      } 
     } 
     catch (Throwable t){ 

     } 
    }//run 
    });//background 
    timer.start(); 
}//onStart 


@Override 
public void onPause(){ 
    synchronized (timer) { 
     try { 
      timer.wait(); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
    pause = true; 
} 

@Override 
public void onResume(){ 
    super.onResume(); 
    if(pause){ 
     synchronized (timer) { 
      timer.notify(); textSec.postInvalidate(); 
      pause = false; 
     } 
    } 
} 

當我按下home鍵,該線程將不會停止,當我回到應用程序,用戶界面是凍結。我不明白爲什麼。

我需要的是當我按主頁按鈕的線程暫停,當我回到線程運行和UI不凍結。

我很欣賞你寫的所有幫助我的代碼。非常感謝你。


UPDATE

我已經把timer.wait()run()這樣的:

@Override 
public void onStart() 
{ 
    super.onStart(); 

    if(!pause){ 
     timer = new Thread(new Runnable() { 
      public void run() { 
      try 
      { 
       while(jalan){ 
        if(running){ 
         Thread.sleep(1000); 
         waktu--; 
         Message msg = handler.obtainMessage(1, waktu); 
         handler.sendMessage(msg); 
         Log.v("Timer Thread", "Thread Berjalan "+waktu); 
         if(waktu==0){ 
          Log.v("Thread Timer", "Waktu Berhenti"); 
          running = false; 
         } 
         if(pause){ 
          synchronized (timer) { 
           timer.wait(); 
          } 
         } 
        } 
       } 
      } 
      catch (Throwable t){  
      } 
     }//run 
     });//background 
     timer.start(); 
    } 

}//onStart 

timer.notify()onResume()就像上面,當我按下家裏談到強制關閉。這裏的日誌說:

07-19 10:27:41.173: E/AndroidRuntime(2280): FATAL EXCEPTION: main 
07-19 10:27:41.173: E/AndroidRuntime(2280): android.app.SuperNotCalledException: Activity {com.konsep.baby.scratch/com.konsep.baby.scratch.BabyScratchChallenge} did not call through to super.onPause() 
07-19 10:27:41.173: E/AndroidRuntime(2280):  at android.app.Activity.performPause(Activity.java:3854) 
07-19 10:27:41.173: E/AndroidRuntime(2280):  at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1191) 
07-19 10:27:41.173: E/AndroidRuntime(2280):  at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2341) 
07-19 10:27:41.173: E/AndroidRuntime(2280):  at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2311) 
07-19 10:27:41.173: E/AndroidRuntime(2280):  at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2291) 
07-19 10:27:41.173: E/AndroidRuntime(2280):  at android.app.ActivityThread.access$1700(ActivityThread.java:117) 
07-19 10:27:41.173: E/AndroidRuntime(2280):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:938) 
07-19 10:27:41.173: E/AndroidRuntime(2280):  at android.os.Handler.dispatchMessage(Handler.java:99) 
07-19 10:27:41.173: E/AndroidRuntime(2280):  at android.os.Looper.loop(Looper.java:123) 
07-19 10:27:41.173: E/AndroidRuntime(2280):  at android.app.ActivityThread.main(ActivityThread.java:3683) 
07-19 10:27:41.173: E/AndroidRuntime(2280):  at java.lang.reflect.Method.invokeNative(Native Method) 
07-19 10:27:41.173: E/AndroidRuntime(2280):  at java.lang.reflect.Method.invoke(Method.java:507) 
07-19 10:27:41.173: E/AndroidRuntime(2280):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
07-19 10:27:41.173: E/AndroidRuntime(2280):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
07-19 10:27:41.173: E/AndroidRuntime(2280):  at dalvik.system.NativeStart.main(Native Method) 

我的代碼有什麼問題?

回答

1

第一個問題是Activity的生命週期實際上如何工作。當您進入主屏幕時,您當前的Activity一直進入停止狀態(即調用onStop())。因此,當您返回到應用程序時,您將收到onStart(),然後onResume()。現在,讓我們來看看基於這些信息在你的代碼會發生什麼:

  1. 第一次啓動,一個新的線程在onStart()創建並啓動。由於布爾標誌,onResume()不做任何事情。
  2. 按下HOME鍵,onPause()被調用時,這個線程調用wait()
  3. 返回給應用程序,onStart()被稱爲現在計時器指向一個新的主題,讓你的舊線晃來晃去。
  4. onResume()被調用,notify()被髮送到新的線程實例。

所以這裏的問題是線程你wait()和線程你notify()不是同一個對象。

第二個問題是wait()實際上做了什麼。從Java文檔(強調):

導致調用線程等待,直到另一個線程調用該對象的通知()或notifyAll的()方法。該方法只能由擁有該對象監視器的線程調用;請參閱notify()有關線程如何成爲監視器的所有者的信息。

調用上的Threadwait()不創建Thread塊,它會阻止線程調用的方法,在這種情況下,在主線程。所以你已經編寫了一個應用程序,它在暫停期間成功地阻止了主線程,並且無法解鎖它,因此凍結。

如果你想使用wait()notify()暫停你的後臺線程,你需要確保wait()從後臺線程中調用(即內部是run()塊)

+0

我已經把'timer.wait()'放在'run()'中,它強制關閉。請看看我的更新。對不起,我是線程新手。 – user1008497 2012-07-19 03:34:44

+0

對不起,錯誤是我的錯。你的回答是對的。非常感謝你 – user1008497 2012-07-19 09:04:28

0

谷歌的培訓頁面已經解釋。 Here

當您的應用程序暫停時,它會停止可能消耗CPU的動畫或其他正在進行的操作。

+0

我仍然不明白這一點,並我的問題有什麼關係? – user1008497 2012-07-19 02:53:55