2012-04-05 119 views
1

在我的應用程序中,我使用此線程來旋轉時鐘上的秒針。但問題是,當我關閉活動時,線程仍然保持運行。我想停止線程,因此它不會影響設備的Bettry。如何在android中停止此線程?

下面是我在哪裏旋轉時鐘的秒針我的活動代碼:

public class ClockActivity extends Activity implements OnClickListener{ 
    private Button chimeBtn; 
    private ImageView img; 
    private Thread myThread = null; 

    @Override 
    public void onCreate(Bundle savedInstanceState){ 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.clock_layout); 


     Runnable runnable = new CountDownRunner(); 
     myThread = new Thread(runnable); 
     myThread.start(); 

     chimeBtn = (Button) findViewById(R.id.chimeBtn); 
     chimeBtn.setOnClickListener(this); 
    } 
    @Override 
    public void onClick(View v) { 
     switch(v.getId()){ 
      case R.id.chimeBtn: 
       playSound(R.raw.one_bell); 
       break; 
     } 
    } 
    public void playSound(int resources){ 

     MediaPlayer mp = MediaPlayer.create(getApplicationContext(), resources); 
      mp.start(); 


    } 

    private void doPlay(){ 
     new Thread(new Runnable() { 

      @Override 
      public void run() { 
       // TODO Auto-generated method stub 

       Log.v("log_tag", "this is seocond thread"); 

      } 
     }).start(); 
    } 
    public void doRotate() { 

     runOnUiThread(new Runnable() { 
      public void run() { 
       try { 

        Date dt = new Date(); 
        int hours = dt.getHours(); 
        int minutes = dt.getMinutes(); 
        int seconds = dt.getSeconds(); 
        String curTime = hours + ":" + minutes + "::" + seconds; 
        Log.v("log_tag", "Log is here Time is now" + curTime); 
        img = (ImageView) findViewById(R.id.imgsecond); 
        RotateAnimation rotateAnimation = new RotateAnimation((seconds - 1) * 6, seconds * 6, 
          Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f); 

        rotateAnimation.setInterpolator(new LinearInterpolator()); 
        rotateAnimation.setFillAfter(true); 

        img.startAnimation(rotateAnimation); 
       } catch (Exception e) { 
        Log.e("log_tag", "Error msg is " + e.toString()); 

       } 
      } 
     }); 
    } 

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 

     if (keyCode == KeyEvent.KEYCODE_BACK) {  
      System.out.println("Back Key Press"); 
      if (myThread != null) { 

        myThread.interrupt(); //says that the myThread should stop 
        try{ 
          myThread.join(); //make this myThread wait for the other myThread to finish before returning 
          myThread = new Thread(); 
          myThread = null; 
        }catch(InterruptedException ie){ 
          //handle the case if the thread.join is interrupt 
          //don't know if this will ever happen, if it can... throw a runtime exception?, or reinterrupt? 
          Thread.currentThread().interrupt(); 
          // reinterrupt because thrown exception cleared interrupt and hope it's handled elsewhere 
        } 

      } 
      System.out.println("Back Key Press"); 
      return true;  
     }  
     return super.onKeyDown(keyCode, event);  
    } 

    @Override 
    public void onDestroy(){ 

     System.out.println("OnDestroy"); 

     super.onDestroy(); 

    } 

    class CountDownRunner implements Runnable { 
     // @Override 
     public void run() { 
      while (!Thread.currentThread().isInterrupted()) { 
       try { 
        // Log.v("log_tag", "Roate is going"); 
        doRotate(); 
        Thread.sleep(1000); 
        //doPlay(); 
        } catch (InterruptedException e) 
        { 
        // Thread.currentThread().interrupt(); 
       } catch (Exception e) { 
        Log.e("log_tag", "Error is " + e.toString()); 
       } 
      } 
     } 
    } 
} 

在此先感謝。

回答

3

請勿在UI線程上使用myThread.join(),因爲它將阻塞,直到線程完成並且您的應用程序可能爲ANR。此外,Thread.currentThread().interrupt();將嘗試中斷非常糟糕的UI線程。

你可以把onDestroyMyThread.interrupt(),或onStop(+重建線程在相應的開始回調)

+0

好的我已經把代碼myThread.interrupt()放在onDestroy中。但它仍然沒有阻止線程。 – 2012-04-05 10:04:08

+0

你應該假設'catch(InterruptedException e)'是停止你的線程的信號。如果你知道了,那麼'isInterrupted()'會在以後返回false(afaik) – zapl 2012-04-05 10:09:10

+0

恩,謝謝你的回答。但仍然沒有停止線程。你可以給任何示例代碼來做到這一點嗎? – 2012-04-05 10:19:53

5

試試這個代碼在你的活動 -

@Override 
protected void onDestroy() { 
    android.os.Process.killProcess(android.os.Process.myPid()); 
} 

當您從您的應用程序退出,您的申請流程並未實際銷燬。如果你銷燬你的進程,所有的子進程(你的所有子線程)都將被銷燬。

+0

什麼是myPid()? – 2012-04-05 10:08:33

+0

不錯的一個。使用這個我得到了我的線程成功停止。但它會影響我的應用程序的其他資源? – 2012-04-05 10:14:53

+0

沒有人,它只會停止你當前的應用程序,它不會妨礙其他資源。 – 2012-04-05 10:18:48

4

好的,這意味着你想創建一個將在後臺運行的服務。有一點是,服務是一種線程,如果它將在後臺運行,將耗盡您的設備電池電量。所以,如果你殺死你的進程,那麼線程以及你的服務將被破壞。所以,停止你的線程 -

boolean running = true; 

public void run() { 
    while(running) { 
     // your working code... 
    } 
} 

@Override 
protected void onDestroy() { 
    running = false; 
} 

當你退出你的應用程序,線程將停止。另一個將繼續運行,這是你的服務。不要試圖強行阻止你的線程,或者暫停。如果線程的while循環中斷,它將被廢棄,然後它會根據JVM規則自動銷燬您的線程。 希望它能幫助你。 玩得開心...

+0

它不能解決線程在原生函數調用中被阻塞的問題,例如在InputStream.read()中。 killProcess()幫助,但不是我的情況 - 我不想殺死整個應用程序,我只需要殺死那個Java線程... – Mixaz 2013-12-08 23:04:51