功能:实现工作线程 & 主线程(ui
线程)之间的通信,即:将工作线程的执行结果传递给主线程,从而在主线程中执行相关的ui
操作。在使用asynctask时,我们无需关注thread和handler,asynctask内部会对其进行管理,这样我们就只需要关注于我们的业务逻辑即可。
属于抽象类,即使用时需 实现子类
public abstract class asynctask {}
参数介绍
params:?开始异步任务执行时传入的参数类型(doinbackground()):
protected abstract result doinbackground(params... params);
对应excute()中传递的参数:
public final asynctask execute(params... params) {
return executeonexecutor(sdefaultexecutor, params);
}
progress:异步任务执行过程中,返回下载进度值的类型,对应onprogressupdate函数传入的参数类型
protected void onprogressupdate(progress... values) {}
?result:异步任务执行完成后,返回的结果类型对应onpostexecute方法传入的参数类型,并且与doinbackground()的返回值类型保持一致
protected void onpostexecute(result result) { }
如下图所示:
asynctask
?核心 & 常用的方法如下:
asynctask
的使用步骤有3个:
- 创建?
asynctask
?子类 & 根据需求实现核心方法 - 创建?
asynctask
子类的实例对象(即 任务实例) - 手动调用
execute()
从而执行异步线程任务
/**
* 步骤1:创建asynctask子类
* 注:
* a. 继承asynctask类
* b. 为3个泛型参数指定类型;若不使用,可用java.lang.void类型代替
* c. 根据需求,在asynctask子类内实现核心方法
*/
private class mytask extends asynctask {
....
/** 方法1:onpreexecute()
*作用:执行 线程任务前的操作
*这个方法会在后台任务开始执行之间调用,用于进行一些界面上的初始化操作,比如显示一个进度
*条对话框等。*/
@override
protected void onpreexecute() {
...
}
/** 方法2:doinbackground()
*作用:接收输入参数、执行任务中的耗时操作、返回 线程任务执行的结果
*必须复写,从而自定义线程任务这个方法中的所有代码都会在子线程中运行,我们应该在这里去处理
*所有的耗时任务。任务一旦完成就可以通过return语句来将任务的执行结果进行返回,如果
*asynctask的第三个泛型参数指定的是void,就可以不返回任务执行结果。注意,在这个方法中是不
*可以进行ui操作的,如果需要更新ui元素,比如说反馈当前任务的执行进度,可以调用
*publishprogress(progress...)方法来完成。
*/
@override
protected string doinbackground(string... params) {
...// 自定义的线程任务
// 可调用publishprogress()显示进度, 之后将执行onprogressupdate()
publishprogress(count);
return string;
}
/**
*作用:在主线程 显示线程任务执行的进度
* 当在后台任务中调用了publishprogress(progress...)方法后,这个方法就很快会被调用,方法
* 中携带的参数就是在后台任务中传递过来的。在这个方法中可以对ui进行操作,利用参数中的数值
*就可以对界面元素进行相应的更新。
*/
@override
protected void onprogressupdate(integer... progresses) {
...
}
/**
*作用:接收线程任务执行结果、将执行结果显示到ui组件
*当后台任务执行完毕并通过return语句进行返回时,这个方法就很快会被调用。返回的数据会作为参
*数传递到此方法中,可以利用返回的数据来进行一些ui操作,比如说提醒任务执行的结果,以及关闭
*掉进度条对话框等。
*/
@override
protected void onpostexecute(string result) {
...// ui操作
}
/*方法5:oncancelled()
* 作用:将异步任务设置为:取消状态
*/
@override
protected void oncancelled() {
...
}
}
/**
* 步骤2:创建asynctask子类的实例对象(即 任务实例)
* 注:asynctask子类的实例必须在ui线程中创建
*/
mytask mtask = new mytask();
/**
* 步骤3:手动调用execute(params... params) 从而执行异步线程任务
* 注:
* a. 必须在ui线程中调用
* b. 同一个asynctask实例对象只能执行1次,若执行第2次将会抛出异常
* c. 执行任务中,系统会自动调用asynctask的一系列方法:onpreexecute() 、doinbackground()、onprogressupdate() 、onpostexecute()
* d. 不能手动调用上述方法
*/
mtask.execute();
asynctask的简单使用-百家乐凯发k8
asynctask的实例必须在主线程中创建。
- asynctask的execute方法必须在主线程中调用。
- onpreexecute()、onpostexecute(result),、doinbackground(params…) 和 onprogressupdate(progress…)这四个方法都是回调方法,android会自动调用,我们不应自己调用。
- 对于一个asynctack的实例,只能执行一次execute方法,在该实例上第二次执行execute方法时就会抛出异常。
asynctask
不与任何组件绑定生命周期,在activity
?或?fragment
中使用?asynctask
时,最好在activity
?或?fragment
的ondestory()
调用?cancel(boolean)
;- 若
asynctask
被声明为activity
的非静态内部类,当activity
需销毁时,会因asynctask
保留对activity
的引用 而导致activity
无法被回收,最终引起内存泄露,使用建议asynctask
应被声明为activity
的静态内部类 -
线程任务执行结果 丢失,当
activity
重新创建时(屏幕旋转 /?activity
被意外销毁时后恢复),之前运行的asynctask
(非静态的内部类)持有的之前activity
引用已无效,故复写的onpostexecute()
将不生效,即无法更新ui操作。(解决方法:在activity
恢复时的对应方法 重启 任务线程) - execute()和executeonexecutor有何区别
execute():这个函数让任务是以单线程队列方式或线程池队列方式运行,会让任务以后台单线程串行方式执行。
executeonexecutor():这个方法通常和thread_pool_executor一起使用,允许多个任务在由asynctask管理的线程池中并行执行。new mytask().executeonexecutor(asynctask.thread_pool_executor,5);
?