我们一般用Thread+Handler实现多线程,将耗时操作运行在另一线程中,任务完成后通过Message通知主线程的Handler进行UI更新。需要编写Thread和Handler。
为了让代码更加统一,Android提供了助手类AsyncTask方便我们使用,其底层也是Thread+Handler。
1. 创建子类时需要指定三个泛型类型:Params, Progress, Result
Params:AsyncTask执行任务的参数的类型
Progress:在后台线程处理的过程中,可以阶段性地发布结果的数据类型
Result:任务全部完成后所返回的数据类型
2. 子类可实现方法:
任务执行会依次调用以下方法
1)onPreExecute() 任务开始前执行
2)doInBackground(Params) 单独线程的任务,可调用publishProgress(Progress…)将阶段性结果发布,在UI线程中回调onProgressUpdate()
3)onProgressUpdate(Progress) 阶段性处理UI
4)onPostExecute(Result) 任务完成后根据返回值更新UI
3. 调用AsyncTask的execute()执行任务(Demo)
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context=UseAsyncTask.this;
String url = "http://../xxx.apk";
//执行异步任务
new MyAsyncTask().execute(url);
}
class MyAsyncTask extends AsyncTask<String,Integer,String>{
int percent;
/**
* 在UI线程上,在任务开始前执行
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
//显示一个进度条
if (!isFinishing()) {
pBar = new ProgressDialog(context);
pBar.setTitle("正在下载");
pBar.setMessage("请稍候...");
pBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);// 水平
pBar.setMax(100);
pBar.setCancelable(false);
pBar.show();
}
}
/**
* 运行在单独线程的任务
* 每完成一步可通过调用AsyncTask的publishProgress(Progress…)将阶段性的处理结果发布出去,在UI线程中回调方法onProgressUpdate
* @param strings
* @return 线程完成后的结果
*/
@Override
protected String doInBackground(String... params) {
//下载文件
//...params[0]
String fileName="";
//阶段性处理:更新下载进度
this.publishProgress(params);
//返回文件名
return fileName;
}
/**
* 阶段性处理UI
*/
@Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
//更新进度条进度
if (pBar != null) {
pBar.setProgress(progress[0]);
}
}
/**
* 任务完成后根据返回值更新UI
* @param result
*/
@Override
protected void onPostExecute(String result) {
super.onPostExecute(s);
//关闭进度条
if (pBar != null && pBar.isShowing()) {
pBar.dismiss();
pBar = null;
}
if (!TextUtils.isEmpty(result)) {
//安装文件
//...
}else{
//下载失败
}
}
}
其他
- AsyncTask的实例创建和execute方法的调用必须在主线程中。
- 一个实例只能调用一次execute方法,第二次调用报异常。
参考自:https://blog.csdn.net/qq_17007915/article/details/50683835