Android开发中,总免不了开启子线程去实现一些耗时的操作,因为如果阻塞主线程的话,应用可能就无响应了。Android中的线程是Java中的线程,我们都知道实现线程有两种方式,一种是继承Thread类,一种是实现Runnable接口。有关多线程,详情请看,Android(线程一) 线程。但是值得高兴的是Android系统提供了一个类,AsyncTask即异步任务,该类封装了线程以及更新UI,所以很有必要仔细研究AsyncTask类。
本篇博文主要描述AsyncTask的使用以及简单说明,下篇文章将结合AsyncTask的源码来深度解析。
下面通过一个实例来展示AsyncTask的使用。
public class MainActivity extends AppCompatActivity {
TextView tv;
Button btn;
private ProgressDialog mDialog = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
btn = (Button) findViewById(R.id.btn);
mDialog = new ProgressDialog(MainActivity.this);
mDialog.setMax(100);
mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new DownloadTask().execute();
}
});
}
class DownloadTask extends AsyncTask<Void, Integer, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
mDialog.show();
}
@Override
protected String doInBackground(Void... params) {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(i);
}
return "success";
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
mDialog.setProgress(values[0]);
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
mDialog.dismiss();
tv.setText(s);
}
}
}
点击按钮后实例化AsyncTask并且执行execute()方法。效果截图如下,
可以看出使用AsyncTask做异步操作是比较简单的。我们都没有自定义Handler等等。有关Handler,详情请看 Android 更新UI的几种方法,Android 源码解析Handler处理机制(一), Android 源码解析Handler处理机制(二)。
下面我们先简单介绍AsyncTask的使用说明。
1.在继承AsyncTask时我们可以为AsyncTask类指定三个泛型参数, 即 AsyncTask<Params, Progress, Result> ,我们在上述例子中创建AsyncTask,定义如下, class DownloadTask extends AsyncTask<Void, Integer, String>
这三个参数定义如下:
(1). Params
是 doInBackground(Void... params)方法的参数,在执行AsyncTask时需要传入的参数,根据实际情况看是否需要传入;如果不需要参数,则使用Void;
(2). Progress
是onProgressUpdate(Integer... values)方法的参数,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位;如果不需要参数,则使用Void;
(3). Result
是 onPostExecute(String s)方法的参数,当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型;如果不需要参数,则使用Void。
2.AsyncTask提供烦人4个比较核心的方法,它们的定义如下所示,
(1).onPreExecute();
该方法运行在主线程中,做一些准备工作,例如显示一个进度条;
(2).doInBackground();
该方法运行在子线程中,内部是耗时操作,执行完毕将调用onPostExecute()方法。如果要更新进度条,则需要手动调用publishProgress()方法,该方法会发送消息调用onProgressUpdate()方法;
(3).onProgressUpdate();
该方法运行在主线程中,用于更新进度;
(4).onPostExecute();
该方法运行在主线程中,当任务执行完毕后的一些操作,例如去掉进度条显示。
其中doInBackground()方法是必须要实现的。其他的方法根据实际情况看是否需要重写。
有关AsyncTask的简单使用说明,就是这么多!也许你觉得这些已经足够了,但是你知道AsyncTask的内部是怎么实现的吗?下篇文章将通过源码来分析AsyncTask。详情请看,Android 源码解析AsyncTask(二)。