Android執行緒的建立與銷燬

yangxi_001發表於2014-02-24
在Android開發中經常會使用到執行緒,一想到執行緒,很多同學就立即使用new Thread(){...}.start()這樣的方式。這樣如果在一個Activity中多次呼叫上面的程式碼,那麼將建立多個匿名執行緒,程式執行的越久可能會越來越慢。因此,需要一個Handler來啟動一個執行緒,以及刪除一個執行緒,保證執行緒不會重複的建立。 

1、建立Handler的一般方式 
 一般會使用Handler handler = new Handler(){...}建立。這樣建立的handler是在主執行緒即UI執行緒下的Handler,即這個Handler是與UI執行緒下的預設Looper繫結的。Looper是用於實現訊息佇列和訊息迴圈機制的。 
 因此,如果是預設建立Handler那麼如果執行緒是做一些耗時操作如網路獲取資料等操作,這樣建立Handler是不行的。 

2、使用HandlerThread 
HandlerThread實際上就一個Thread,只不過它比普通的Thread多了一個Looper。我們可以使用下面的例子建立Handler 
HandlerThread thread = new HandlerThread("MyHandlerThread"); 
thread.start(); 
mHandler = new Handler(thread.getLooper()); 
mHandler.post(mBackgroundRunnable); 
建立HandlerThread時要把它啟動了,即呼叫start()方法。然後建立Handler時將HandlerThread中的looper物件傳入。那麼這個mHandler物件就是與HandlerThread這個執行緒繫結了(這時就不再是與UI執行緒繫結了,這樣它處理耗時操作將不會阻塞UI)。 
最後把實現耗時操作的執行緒post到mHandler的訊息佇列裡面。注意的是,mBackgroundRunnable這個執行緒並沒有啟動,因為沒有呼叫start()方法。 

3、完整的angrycode 
public class MainActivity extends Activity implements OnClickListener{ 
public static final String TAG = "MainActivity"; 

private Handler mHandler; 

private boolean mRunning = false; 

private Button mBtn; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.activity_main); 
HandlerThread thread = new HandlerThread("MyHandlerThread"); 
thread.start();//建立一個HandlerThread並啟動它 
mHandler = new Handler(thread.getLooper());//使用HandlerThread的looper物件建立Handler,如果使用預設的構造方法,很有可能阻塞UI執行緒 
mHandler.post(mBackgroundRunnable);//將執行緒post到Handler中 

mBtn = (Button)findViewById(R.id.button); 
mBtn.setOnClickListener(this); 

@Override 
protected void onResume() { 
super.onResume(); 
mRunning = true; 

@Override 
protected void onStop() { 
super.onStop(); 
mRunning = false; 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
// Inflate the menu; this adds items to the action bar if it is present. 
getMenuInflater().inflate(R.menu.main, menu); 
return true; 

//實現耗時操作的執行緒 
Runnable mBackgroundRunnable = new Runnable() { 

@Override 
public void run() { 
//----------模擬耗時的操作,開始--------------- 
while(mRunning){ 

Log.i(TAG, "thread running!"); 

try { 
Thread.sleep(200); 
} catch (InterruptedException e) { 
e.printStackTrace(); 


//----------模擬耗時的操作,結束--------------- 

}; 
@Override 
protected void onDestroy() { 
super.onDestroy(); 
//銷燬執行緒 
mHandler.removeCallbacks(mBackgroundRunnable); 


@Override 
public void onClick(View v) { 
Toast.makeText(getApplication(), "click the button!!!", Toast.LENGTH_SHORT).show(); 


 上面的angrycode中,如果在onCreate()方法中裡面沒有使用HandlerThread而是在直接使用Handler的預設構造方法來建立Handler,那麼mBackgroundRunnable將會阻塞UI執行緒。 

4、執行緒銷燬 
 用上面的方式來建立執行緒,在銷燬時就可以使用
mHandler.removeCallbacks(mBackgroundRunnable); 
銷燬一個執行緒,這樣就可以避免在多次進入同一個Activity時建立多個同時執行著的執行緒。 

相關文章