Android : 執行緒的結束,掛起和恢復(上)

yangxi_001發表於2016-05-27

Android應用的開發過程中, 我們有時候需要通過建立一個新的執行緒去完成一些任務。例如,我們去進行搜尋動作,如果搜尋比較費時,我們就需要通過進度條來提示使用者搜尋的進展情況,避免使用者認為發生了當機。此時進度條的重新整理就需要另外一個執行緒去實現。

但是這裡有一個誤區 : 有些人在多執行緒開發的時候會錯誤的認為,如果我們從建立執行緒的Activity中退出(該Acitivity被銷燬),則在該Activity中建立的自定義執行緒也會被銷燬。其實這是大錯特錯了。

實踐證明,上述情況下,建立的執行緒並不會自動銷燬,而是仍然在後臺默默無聞地執行,直到自行結束。Android的這種設計是無可厚非的。從理論上來解釋,應用的最小執行單位是執行緒,最小資源單位是程式,一個程式可以包含多個執行緒,而多個執行緒共享同一個所屬程式的資源。因此,個人理解Android的應用其實就是一個程式,而裡面的每個UI, Activity就是從屬這個程式的執行緒,從一個Activity進入另外一個Activity本質就是將之前的執行緒掛起,然後建立後面的執行緒。退出也是同理。自定義執行緒也是遵循這個原則的。除非去控制某個執行緒結束,否則只有當該現程執行完畢或者所屬的程式被銷燬,該執行緒才會真正的結束。

綜上,當我們在自定義執行緒還沒有執行完畢的情況下,需要結束相關動作的時候,我們就要認為地去結束相關執行緒。例如,在搜尋過程中,我們不想去繼續搜尋,而退出了搜尋功能,此時我們就需要去結束自定義的搜尋執行緒。如果不這樣會可能造成嚴重錯誤。例如,我們反覆進入搜尋功能去搜尋,在搜尋未結束時退出,然後再進入。這種情況下,由於之前的自定義執行緒並未結束,而之後又會有多個新搜尋執行緒被建立執行,很容易導致臨界區衝突,從而導致裝置當機。

那麼我們如何控制這些自定義執行緒呢?以下筆者將給與詳細說明。

 

一. 執行緒的結束

 

其實,通過幫助文件,我們可以知道,Android的執行緒類本身就提供一些公共方法去結束執行緒。

void  destroy()    

This method is deprecated. Not implemented.

synchronized final void  stop(Throwable throwable)

This method is deprecated. because stopping a thread in this manner is unsafe and can leave your application and the VM in an unpredictable state.

final void  stop()

This method is deprecated. because stopping a thread in this manner is unsafe and can leave your application and the VM in an unpredictable state

 

        但是,通過說明我們可以看到,這些方法Android本身都是不推薦使用的,通過這種方式結束執行緒是不安全的,可能會讓我們的應用退出,並且會讓虛擬機器處於一種無法預料的狀態。那麼開發過程中,在合情合理的需求中,我們怎麼去安全的結束指定的自定義執行緒呢?筆者來救贖了。

1.    我們可以在自定義執行緒類中定義一個布林私有變數,並且初始化為假,用於記錄執行緒的執行狀態。

2.    run函式開始,設定該變數為真,表示執行緒進入執行狀態。

3.    run函式結束位置,設定該變數為假,表示執行緒進入結束狀態。

4.    run的執行緒執行部分,我們可以找一些鍥點,對該變數進行判斷,如果為真則繼續執行,否則退出run函式。

5.    在自定義執行緒類中再提供一個公共函式,該函式的作用是將上述狀態變數設定為假。

     這樣,當自定義執行緒執行還未結束時,我們就可以通過呼叫5中的方法將執行緒安全結束。

        思想的本質就是,既然我們不能安全強制結束執行緒,那我們就讓它安全地提前退出。效果是一樣的。

程式例項 :

    class SearchThread extends Thread

   {    

      private boolean isRun = false ;

     

      public SearchThread()

      {        

          isRun = false ;      

      }

            

      public void setStopState()

      {

          isRun = false ;

      }

 

@Override

      public void run()

    {

       isRun = true ;

       ……

       //---執行緒執行部分,僅僅舉例為了說明-----

      for(int i = 0; i < 100; i++)

      {

          if(isRun == false) return ;

          ……

          for(int j = 0; j < 100; j++)

          {

               if(isRun == false) return ;

               ……

          }

}

       //-----end----------

       ……

      }

}

 

相關文章