Android开发--取消AsyncTask

天下之事常成于困约,而败于奢靡。这篇文章主要讲述Android开发--取消AsyncTask相关的知识,希望能为你提供帮助。
      在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);

【Android开发--取消AsyncTask】  值得注意的是,调用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()中的任务。

    推荐阅读