Android開發--取消AsyncTask
阿新 • • 發佈:2017-06-01
cas stop gre term you 調用 asynctask tac let
在Android應用開發過程中,為了防止UI線程堵塞,耗時的工作都應該另起一個後臺線程來完成,其中AsyncTask就是其中的一種方式。最近在案子中需要“停止/取消”某個AsyncTask,在網上查了些資料,這裏做個筆記。
查看AsyncTask.java文件,其中有個cancel()函數,可以通過調用cancel(true)來停止正在運行的AsyncTask。
/** * <p>Attempts to cancel execution of this task. This attempt will * fail if the task has already completed, already been cancelled, * or could not be cancelled for some other reason. If successful, * and this task has not started when <tt>cancel</tt> is called, * this task should never run. If the task has already started, * then the <tt>mayInterruptIfRunning</tt> parameter determines * whether the thread executing this task should be interrupted in * an attempt to stop the task.</p> * * <p>Calling this method will result in {@link #onCancelled(Object)} being * invoked on the UI thread after {@link #doInBackground(Object[])} * returns. Calling this method guarantees that {@link #onPostExecute(Object)} * is never invoked. After invoking this method, you should check the * value returned by {@link #isCancelled()} periodically from * {@link #doInBackground(Object[])} to finish the task as early as * possible.</p> * * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this * task should be interrupted; otherwise, in-progress tasks are allowed * to complete. * *@return <tt>false</tt> if the task could not be cancelled, * typically because it has already completed normally; * <tt>true</tt> otherwise * * @see #isCancelled() * @see #onCancelled(Object) */ public final boolean cancel(boolean mayInterruptIfRunning) { mCancelled.set(true);
值得註意的是,調用cancel(true)函數需要註意以下幾點:
1.當AsyncTask已經完成,或則以及被取消,亦或其他原因不能被取消,調用cancel()會失敗;
2.如果AsyncTask還沒有開始執行,調用cancel(true)函數後,AsyncTask不會再執行;
3.如果AsyncTask已經開始執行,參數mayInterruptIfRunning決定是否立即stop該Task;
4.調用cancel()後,doInBackground()完成後,不再調用onPostExecute(),而是執行onCancelled();
下面是一個簡單的Demo,使用兩個Button,分別用來start & stop AsyncTask。
import android.os.AsyncTask; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private static final String TAG = "AsyncTaskTest"; private TestTask task = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.btn1).setOnClickListener(this);//start async task btn findViewById(R.id.btn2).setOnClickListener(this);//stop async task btn } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn1: task = new TestTask(); task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); break; case R.id.btn2: if (task != null && !task.isCancelled() && task.getStatus() == AsyncTask.Status.RUNNING) { task.cancel(true); task = null; } break; } } class TestTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { int count = 5; while (count > 0) { count--; if (isCancelled()) { //通過isCancelled()判斷cancel(true)是否成功。 Log.d(TAG,"Cancel"); break; } Log.d(TAG,"Start Sleep"); try { Thread.sleep(2000);//模擬耗時操作 } catch (InterruptedException e) { e.printStackTrace(); } Log.d(TAG,"End Sleep"); } return null; } @Override protected void onPostExecute(Void aVoid) { Log.d(TAG,"onPostExecute"); super.onPostExecute(aVoid); } @Override protected void onCancelled() { Log.d(TAG,"onCancelled"); super.onCancelled(); } } }
當然真實案例中,在doInBackground()函數中,不像Demo中只有一個簡單的while()循環,所以可能需要多加幾個isCancelled()來結束doInBackground()中的任務。
Android開發--取消AsyncTask