原文链接:http://www.jufanshare.com/content/124.html
本教程附Demo:https://gitee.com/qwertiddler/AsyncTask.git
在Android中耗时任务是不能在主线程中执行的,否则会造成线程阻塞,阻塞超过5秒则会出现ANR导致应用崩溃。所以在这时候我们就需要去专门去异步线程处理耗时任务。
Android如何处理耗时任务?
作为Android初学者,并且熟悉Java的童鞋肯定想着新开一个异步线程来处理耗时任务就可以啊。想象中的代码如下:
new Thread(new Runnable() {
@Override
public void run() {
//处理耗时操作
}
}).start();
其实不然,这样自己开一个线程的方式肯定是可以的,但是并不方便,并且会遇到很多问题(异步更新UI、线程消息等),异步更新UI还要借助Handler等。其实非常不理想,使用起来复杂化了。
Android早就考虑过处理耗时任务的情况,并且有成熟的解决方案,也就是使用Android AsyncTask。
AsyncTask简单介绍
异步情况下,我们自己新建一个class然后继承AsyncTask类,并且实现抽象方法doInBackground()。如下:
public class TestAsyncTask extends AsyncTask {
@Override
protected Integer doInBackground(Integer... integers) {
return null;
}
}
注意,继承AsyncTask类的时候,需要指定3个泛型参数,如果不需要泛型参数,指定为Void,如下:
public class TestAsyncTask extends AsyncTask {
@Override
protected Integer doInBackground(Void... voids) {
return null;
}
}
第一个泛型指定为Void,发现doInBackground()方法接收的参数也随之而变为Void了。也就是说,第一个泛型中的参数是直接给doInBackground()方法使用的。
Android启动AsyncTask异步任务
异步任务基本处理做好了后,如何启动呢?代码如下:
new TestAsyncTask().execute(1);
也就是实例化继承了AsyncTask类的异步处理类TestAsyncTask,然后调用execute()方法,execute()方法可接收一个可变参数,参数类型对应AsyncTask三个泛型中的第一个泛型的类型,并且在doInBackground()方法中取出使用,代码如下:
@Override
protected Integer doInBackground(Integer... ints) {
Integer count = ints[0];
}
好了,到此,Android使用AsyncTask处理耗时任务到此结束,你的所有耗时任务都可以在doInBackground()方法中处理。具体演示请看文章开始的Demo。
Android AsyncTask常用方法介绍
AsyncTask中,除了doInBackground()方法外,还有很多可以重写的方法,下面就一个个简单介绍下,具体的还是要自己去尝试。
onPreExecute() 在异步任务启动前(也就是doInBackground()方法执行之前)调用,可以做一些初始化操作。
onPostExecute() 在异步任务执行完成的时候调用,并且接收一个可变参数,参数对应AsyncTask三个泛型的第三个参数。
onProgressUpdate() 在异步任务执行过程中,也就是doInBackground()执行时调用,但是需要代码手动调用,也就是在doInBackground()方法中调用publishProgress()方法就会触发onProgressUpdate()的执行,用于处理异步任务的进度,当然也可以接收一个可变参数,对应AsyncTask的第二个泛型参数。
onCancelled() 在异步任务取消的时候调用,注意,此方法不会和onPostExecute()同时调用,二者只能调用一个,异步任务如何取消呢?和前面介绍的启动异步任务一样,在异步任务类对象上调用cancel(true)方法。
注:继承了AsyncTask的异步任务类中的所有方法除doInBackground()外都是在UI线程中执行。
异步任务类完整代码
package com.jufanshare.asynctask.task;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class TestAsyncTask extends AsyncTask {
private final String TAG="TestAsyncTask";
private TextView textView;
private ProgressBar progressBar;
private Context context;
public TestAsyncTask(TextView textView, ProgressBar progressBar, Context context) {
this.textView = textView;
this.progressBar = progressBar;
this.context = context;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.d(TAG,"方法_______onPreExecute()_______执行所在线程_________"+Thread.currentThread().getName()+"______________");
}
@Override
protected Integer doInBackground(Integer... ints) {
Integer count = ints[0];
while (count<50&&!isCancelled()){//isCancelled()表示判断当前任务是否被取消,防止在取消异步任务的时候循环不能及时停下
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++;
Log.d(TAG,"方法_______doInBackground()_______执行所在线程_________"+Thread.currentThread().getName()+"_______"+count+"_______");
publishProgress(count);
}
return count;
}
@Override
protected void onPostExecute(Integer i) {
// 任务执行onCancelled()回调的时候不会执行当前onPostExecute()方法
Log.d(TAG,"方法_______onPostExecute()_______执行所在线程_________"+Thread.currentThread().getName()+"______________");
textView.setText(i+"");
}
@Override
protected void onProgressUpdate(Integer... values) {
Log.d(TAG,"方法_______onProgressUpdate()_______执行所在线程_________"+Thread.currentThread().getName()+"______________");
textView.setText(values[0]+"");
progressBar.setProgress(values[0]);
}
@Override
protected void onCancelled() {
Log.d(TAG,"方法_______onCancelled()_______执行所在线程_________"+Thread.currentThread().getName()+"______________");
super.onCancelled();
Toast.makeText(context,"任务取消成功",Toast.LENGTH_LONG).show();
}
}
Activity代码
package com.jufanshare.asynctask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.jufanshare.asynctask.task.TestAsyncTask;
public class MainActivity extends AppCompatActivity {
private TextView textView;
private ProgressBar progressBar;
private TestAsyncTask testAsyncTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textView);
progressBar=(ProgressBar)findViewById(R.id.progressBar);
}
public void doTaskClick(View view){
testAsyncTask = new TestAsyncTask(textView, progressBar,this);
//执行异步任务
testAsyncTask.execute(1);
}
public void cancelTaskClick(View view){
//取消异步任务
testAsyncTask.cancel(true);
}
}