版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
利用AsyncTask我们可以在子线程中进行一些耗时操作,然后在通知主线程更新UI,我们以下载为例:
/**
* @Author: david.lvfujiang
* @Date: 2019/10/15
* @Describe:
*/
public class DownloadTask extends AsyncTask<String, Integer, Boolean> {
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.e("启动", "启动");
}
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
if (aBoolean == true){
Log.e("结束", "结束");
}
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
Log.e("进度", String.valueOf(values));
}
@Override
protected Boolean doInBackground(String... strings) {
for (int i = 0; i < 10; i++) {
if (isCancelled()) {
Log.e("cancell", isCancelled()+"");
break;
}
else {
publishProgress(new Integer(i));
Log.e("cancell", isCancelled()+"");
}
}
return true;
}
}
1.继承AsyncTask<String, Integer,Boolean>,三个泛型参数对应的是:
// a. 开始异步任务执行时传入的参数类型,对应excute()、doInBackground()中传递的参数
// b. 异步任务执行过程中,返回下载进度值的类型对应onProgressUpdate()、publishProgress()中传递的参数
// c. 异步任务执行完成后,返回的结果类型,与doInBackground()的返回值类型、onPostExecute()传递参数保持一致
2.调用方法如下:
DownloadTask task= new DownloadTask();
task.execute("name");
3.执行流程:
系统调用顺序是
1.onPreExecute() 【在这个方法我们可以进行一些初始化操作,比如实例化进度条等】
2.doInBackground(String name) 【这个方法是运行在子线程,我们可以进行我们的耗时任务,我们可以每隔一秒在这个方法里调用一次publishProgress(Integer i),之后系统将执行onProgressUpdate(Integer i)】
3.onProgressUpdate(Integer... values)【这个方法运行在主线程,每次调用publishProgress()后它也会被调用,所以我们可以在这里面进行UI更新】
4.onPostExecute(Boolean aBoolean) 【doInBackground()方法执行完后这个方法将会执行,我们可以在这做一些收尾工作】
注:
a. 必须在UI线程中调用
b. 同一个AsyncTask实例对象只能执行1次,若执行第2次将会抛出异常
java.lang.IllegalStateException: Cannot execute task: the task has already been executed (a task can be executed only once)
c. 执行任务中,系统会自动调用AsyncTask的一系列方法:onPreExecute() 、doInBackground()、onProgressUpdate() 、onPostExecute()
d. 不能手动调用上述方法
e.当我们需要执行新的耗时操作时再创建一个calsse.
f .当如果我们异步任务想要停止的话可以调用cancell( Boolean b)方法,但是cancel()仅仅是给AsyncTask对象设置了一个标识位,当调用了cancel()后,发生的事情只有:AsyncTask对象的标识位变了,doInBackground()和 onProgressUpdate()还是会继续执行直到doInBackground()结束,而onPostExecute()不会被回调。所以我们需要在doInBackground()的每次循环中调用isCancelled()去判断是否继续执行任务。