手记

AsyncTask实现异步任务执行

AsyncTask实现异步任务执行
查看源码AsyncTask只是对Thread和Handler的一个封装。

基本概念
3个泛型参数
AsyncTask <Params, Progress, Result>
Params: 指定的是我们传递给异步任务执行时的参数的类型
Progress: 指定的是我们的异步任务在执行的时候将执行的进度返回给UI线程的参数的类型
Result: 指定的是异步任务执行完后返回给UI线程的结果的类型
我们在定义一个类继承AsyncTask类的时候,必须指定好这三个泛型的类型,如果都不指定的话,则都将其写成Void
4个执行步骤
onPreExecute():UI Thread当中执行,这个方法是在执行异步任务之前的时候执行,我们可以在异步任务执行前做UI提示
doInBackground(Params... params):这个方法就是来处理异步任务的方法,执行耗时操作。这个方法也是必须要实现的抽象方法。
onProgressUpdate(Progess... values):UI Thread当中执行,用来更新进度条等
onPostExecute(Result... result):UI Thread当中执行,当异步任务执行完之后,将doInBackground结果返回给这个方法来更新UI
2种执行方式
后台线程可以设置为串行或者并行执行
串行:execute(Params... params)
并行:executeOnExecutor(Executor exec, Params... params)
注意:各SDK版本execute默认执行方式不统一,1.5中顺序执行,1.6到 2.3中并行执行,3.0以后又改回串行执行,并添加并行执行接口executeOnExecutor
注意事项
必须在UI线程中加载和创建,以及调用execute
不能做特别耗时的操作,建议只几秒内的异步任务
一个AsyncTask对象只能被执行一次,即只能调用一次execute,否则会抛出异常报错
Caused by: java.lang.IllegalStateException: Cannot execute task: the task has already been executed (a task can be executed only once)
不能在程序中主动调用4个步骤
代码示例
// 初始化AsyncTask及执行
protected void function() {
...
// 串行执行,识别一张bitmap,每次执行前都需要重新new一个对象
mClassifierAsyncTask = new ClassifierAsyncTask();
mClassifierAsyncTask.execute(bitmap);
}

// 自定义AsyncTask任务类,实现doInBackground
private ClassifierAsyncTask mClassifierAsyncTask;
private class ClassifierAsyncTask extends AsyncTask<Bitmap , Void, String >{

@Overrideprotected void onPreExecute() {    super.onPreExecute();
    mTvResult.setText(getString(R.string.classifying));
}@Overrideprotected String doInBackground(Bitmap... bitmaps) {    if(mMyTfClassifier == null) {
        mMyTfClassifier = new MyTfClassifier(MainActivity.this);
    }
    String result = mMyTfClassifier.recognizeImage(bitmaps[0]);    return result;
}@Overrideprotected void onPostExecute(String result) {    super.onPostExecute(result);
    mTvResult.setText(result);
}

}
存在的问题
Activity屏幕旋转或销毁时,如果AsyncTask没有执行完毕就会存在内存泄露。特别是屏幕旋转时AsyncTask没有执行完毕,会导致屏幕异常。



作者:凯恩_Kane
链接:https://www.jianshu.com/p/cc4805ff78f7


0人推荐
随时随地看视频
慕课网APP