AsyncTask:
AsyncTask的使用:
- 创建 AsyncTask 子类 & 根据需求实现核心方法
private class MyTask extends AsyncTask<Params, Progress, Result> {
....
// 方法1:onPreExecute()
// 作用:执行 线程任务前的操作,此方法运行在主线程中,可以对控件进行初始化的操作
// 注:根据需求复写
@Override
protected void onPreExecute() {
...
}
// 方法2:doInBackground()
// 作用:接收输入参数、执行任务中的耗时操作、返回 线程任务执行的结果,此方法运行在子线程中,比较耗时的操作放在此方法中执行
// 注:必须复写,从而自定义线程任务
@Override
protected String doInBackground(String... params) {
...// 自定义的线程任务
// 可调用publishProgress()显示进度, 之后将执行onProgressUpdate()
publishProgress(count);
}
// 方法3:onProgressUpdate()
// 作用:在主线程 显示线程任务执行的进度,触发此方法需要在doInBackground中使用publishProgress方法
// 注:根据需求复写
@Override
protected void onProgressUpdate(Integer... progresses) {
...
}
// 方法4:onPostExecute()
// 作用:接收线程任务执行结果、将执行结果显示到UI组件,此方法运行在主线程中
// 注:必须复写,从而自定义UI操作
@Override
protected void onPostExecute(String result) {
...// UI操作
}
// 方法5:onCancelled()
// 作用:将异步任务设置为:取消状态
@Override
protected void onCancelled() {
...
}
}
抽象类泛型参数:
class MyTask extends AsyncTask<Params, Progress, Result>{
private ImageView ivPic;
private String url;
.........
}
Params:执行AsyncTask需要传入的参数,在MyTask类继承AsyncTask类时,如果不需要传入参数可指定为Void;但MyTask如果定义了私有属性,例如private ImageView ivPic; private String url;,则Params不能指定为Void,可指定为Object,同时这些参数会存入类型为Object的Params数组;
Progress:进度显示单位,可指定为Integer
Result:返回执行结果的数据类型
onPreExcute():运行在主线程中,后台任务开始之前调用,可进行界面的一些初始化操作,如显示一个进度条;
doInBackground():运行在子线程中,不可进行UI操作,用来执行耗时操作,使用return返回执行结果,结果类型与Result类型对应
onProgressUpdate():运行在主线程中,可进行UI操作,显示线程任务执行的进度,触发此方法需要在doInBackground中使用publishProgress方法
onPostExecute():此方法运行在主线程中,接收线程任务执行结果、将执行结果显示到UI组件;执行结果Result会返回到onPostExecute,来执行最后一段操作
- 创建 AsyncTask子类的实例对象(即 任务实例)
MyTask mTask = new MyTask();
- 手动调用execute(()从而执行异步线程任务
mTask.execute();
AsyncTask使用时的注意点
在使用AsyncTask时有一些问题需要注意的:
-
关于 生命周期
结论:AsyncTask不与任何组件绑定生命周期
使用建议:在Activity 或 Fragment中使用 AsyncTask时,最好在Activity 或 Fragment的onDestory()调用mTask.cancel(boolean); -
关于 内存泄漏
结论:若AsyncTask被声明为Activity的非静态内部类,当Activity需销毁时,会因AsyncTask保留对Activity的引用 而导致Activity无法被回收,最终引起内存泄露
使用建议:AsyncTask应被声明为Activity的静态内部类 -
线程任务执行结果 丢失
结论:当Activity重新创建时(屏幕旋转 / Activity被意外销毁时后恢复),之前运行的AsyncTask(非静态的内部类)持有的之前Activity引用已无效,故复写的onPostExecute()将不生效,即无法更新UI操作
使用建议:在Activity恢复时的对应方法 重启 任务线程