轉自: http://www.android-study.com/jichuzhishi/376.html
我們知道在java的線程中,沒有辦法停止一個正在運行中的線程,在Android的AsyncTask中也是一樣的。如果必須要停止一個線程,我們可以採用在這個線程中設定一個標誌位,然後線上程run方法或AsyncTask的doInBackground方法中的關鍵步驟判斷這個標誌位以決定是否繼續執行。然後在需要終止此線程的地方改變這個標誌位以達到停止線程的目的。
從外部調用AsyncTask的cancel方法並不能停止一個已經啟動的AsyncTask,這個cancel方法的作用與線程的interrupt方法相似,調用了一個線程的interrupt方法之後線程仍然運行,但是如果該線程的run方法裡面調用過sleep的或者wait方法後,處於sleep或wait狀態,則sleep和wait立即結束並且拋出InterruptedException異常。AsyncTask的cancel方法也一樣,如果在這個Task的doInBackground方法中調用了sleep或wait方法,當在UI線程中調用了這個Task執行個體的cancel方法之後,sleep或wait立即結束並且拋出InterruptedException異常,但是如果捕獲該異常的代碼後面還有其他代碼,則這些代碼還會繼續執行。測試代碼如下:
package eoe.task; import android.app.Activity;import android.os.AsyncTask;import android.os.Bundle;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button; public class AsyncTaskTest extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // set the six buttons listener Button startButton = (Button) this.findViewById(R.id.StartTask); final TestAsyncTask task = new TestAsyncTask(0); startButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { task.execute("str1", "str2"); } }); Button endButton = (Button) this.findViewById(R.id.StopTask); endButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { task.cancel(false); } }); Button startSleepButton = (Button) this .findViewById(R.id.StartThread_sleep); final ThreadForTestSleep threadForTestSleep = new ThreadForTestSleep(); startSleepButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { threadForTestSleep.start(); } }); Button endSleepButton = (Button) this .findViewById(R.id.StopThread_sleep); endSleepButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { threadForTestSleep.interrupt(); } }); Button startWaitButton = (Button) this .findViewById(R.id.StartThread_wait); final ThreadForTestWait threadForTestWait = new ThreadForTestWait(); startWaitButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { threadForTestWait.start(); } }); Button endWaitButton = (Button) this.findViewById(R.id.StopThread_wait); endWaitButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { threadForTestWait.interrupt(); } }); } /** * AsyncTask * * @author alex * */ private class TestAsyncTask extends AsyncTask<String, Integer, Double> { double a; public TestAsyncTask(double a) { this.a = a; } @Override protected Double doInBackground(String... params) { for (String param : params) { Log.i("TestAsyncTask", "param:" + param); } Log.i("TestAsyncTask", "doInBackground is start"); for (int i = 0; i < 10000000; i++) { a = i * i + i; Log.d("-----", "a:" + a); } Log.i("TestAsyncTask", "sleep 1 is end"); try { Thread.sleep(30000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Log.i("TestAsyncTask", "sleep 2 is end and continue execute"); return a; } protected void onPostExecute(Double result) { Log.i("last a value is", "" + result); } } /** * test sleep * * @author Administrator * */ private class ThreadForTestSleep extends Thread { public void run() { Log.i("ThreadForTestWait", "sleep start"); try { sleep(30000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } double a; for (int i = 0; i < 10000000; i++) { a = i * i + i; Log.d("-----", "a:" + a); } Log.i("ThreadForTestWait", "sleep end"); } } /** * test wait * * @author Administrator * */ private class ThreadForTestWait extends Thread { public void run() { Log.i("ThreadForTestWait", "wait start"); try { synchronized (this) { wait(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Log.i("ThreadForTestWait", "wait end"); } }}
我們來看看這個例子怎麼樣,這裡主要用到了view.View.OnClickListener;監聽,android.widget.Button按鈕,我們定義一個Button是開始,一個Button定義為停止。這樣我們就可以給按鈕加上一個監聽,在監聽裡定義當點擊按鈕時,就可以停止AsyncTask和Thread,這個方法我個人感覺非常的好。這個主要是加了一個sleep(30000);這樣的話,我們就有時間來判斷一下是否應該怎麼樣做。