Android中AsyncTask(异步任务,实际就和handler的作用差不多)
来源:互联网 发布:简易地图软件 编辑:程序博客网 时间:2024/06/12 00:53
提到了两个原因:
AsyncTask的生命周期没有跟Activity的生命周期同步
容易内存泄露
AsyncTask和Activity的生命周期
如果你在一个Activity中创建了一个AsyncTask,你旋转了屏幕,这个Activity将会被销毁并且会重新创建一个新的实例。但是AsyncTask没有销毁,它将会继续执行直到完成。当它执行完成后,它实际上是更新了上一个已经不存在的Activity,如果你原本想在onPostExecute()中更新UI的话,这时的AsyncTask将不会更新新的Activity,并且这个操作会引发一个异常:java.lang.IllegalArgumentException。
如果你是想要在onPostExecute()中关闭一个dialog,则会发生:java.lang.IllegalArgumentException: View not attached to window manager(前提是你忘记在Activity的onStop()中忘记dismiss)。不仅如此,还会在show()的调用出抛出一个lead window的异常
内存泄露问题
在Activity中作为内部类创建AsyncTask很方便。因为AsyncTask在执行完成或者执行中需要使用Activity中的view,因为内部类可以直接访问外部类的域(也就是变量)。然而这意味着内部类会持有外部类的一个引用。
当长时间运行时,因为AsyncTask持有Activity的引用,所以即使当该Activity不再显示时Android也无法释放其占用的资源。
AsyncTask:(实际就和handler的作用差不多)
使用AsyncTask的具体步骤:注意3个泛型必须基本数据类型对象,也就是(Integer,String之类)
1.新建一个类,extends AsyncTask类<Params, Progress, Result>{}//三个泛型可用大写的Void替代(Void是小写void的对象类型)
2.复写其抽象方法,在异步任务(也就是doInBackground方法)执行之前,执行该方法,在主线程执行
protected void onPreExecute() {super.onPreExecute();}
3.复写抽象方法,该方法在后台执行(可以理解为子线程),可以做耗时的工作
protected Result doInBackground(Params... params){return null;}可以接收到doInBackground返回数据
4.复写其方法抽象方法,在异步任务(也就是doInBackground方法)执行之后,执行该方法,在主线程执行
protected void onPostExecute(Void result) {super.onPostExecute(result);}
5.开启一个异步任务,在主线程里新建继承了AsyncTask自定义的类,调用execute()方法.
new myAsyncTasK().execute();//execute()方法一定要用,相当于开启线程的start,调了1个小时的bug.
关于AsyncTask参数的说明
1.类中的三个泛型:
params:第一个泛型,就是5.execute方法的参数类型(其实就是他传的实际参数),也是3.doInBackground方法的参数类型
提示:3.doInBackground(Params... params){内部使用时,params就是对应类型的数组,Prarms[0]就是第一个Params}
Progress:第二个泛型,就是publishProgress(必须在3.doInBackground方法里调用)方法的参数类型,他负责发布进度,类似进度条,
也是onProgressUpdate方法的参数类型,他得到的是来自publishProgress的实际参数,进度更新时调用,在主线程中执行,可更新UI
提示:使用到第二个泛型,就要使用到publishProgress,并继续使用到onProgressUpdate(此方法要复写,具体格式如下:)
protected void onProgressUpdate(Progress... values){super.onProgressUpdate(values);}//alues就是对应类型的数组
Result:第三个泛型,既是3.doInBackground的返回值类型,并且它还是OnPostExecute的参数类型;
应用场景:在子线程(doInBackground)获取信息,在OnpostExcute里去显示;
示例代码:
Android API中有提到,AsyncTask非常适合短时间异步操作。如果要执行长时间操作,最好使用线程池Executor:
提到了两个原因:
AsyncTask的生命周期没有跟Activity的生命周期同步
容易内存泄露
AsyncTask和Activity的生命周期
如果你在一个Activity中创建了一个AsyncTask,你旋转了屏幕,这个Activity将会被销毁并且会重新创建一个新的实例。但是AsyncTask没有销毁,它将会继续执行直到完成。当它执行完成后,它实际上是更新了上一个已经不存在的Activity,如果你原本想在onPostExecute()中更新UI的话,这时的AsyncTask将不会更新新的Activity,并且这个操作会引发一个异常:java.lang.IllegalArgumentException。
如果你是想要在onPostExecute()中关闭一个dialog,则会发生:java.lang.IllegalArgumentException: View not attached to window manager(前提是你忘记在Activity的onStop()中忘记dismiss)。不仅如此,还会在show()的调用出抛出一个lead window的异常
内存泄露问题
在Activity中作为内部类创建AsyncTask很方便。因为AsyncTask在执行完成或者执行中需要使用Activity中的view,因为内部类可以直接访问外部类的域(也就是变量)。然而这意味着内部类会持有外部类的一个引用。
当长时间运行时,因为AsyncTask持有Activity的引用,所以即使当该Activity不再显示时Android也无法释放其占用的资源。
AsyncTask:(实际就和handler的作用差不多)
使用AsyncTask的具体步骤:注意3个泛型必须基本数据类型对象,也就是(Integer,String之类)
1.新建一个类,extends AsyncTask类<Params, Progress, Result>{}//三个泛型可用大写的Void替代(Void是小写void的对象类型)
2.复写其抽象方法,在异步任务(也就是doInBackground方法)执行之前,执行该方法,在主线程执行
protected void onPreExecute() {super.onPreExecute();}
3.复写抽象方法,该方法在后台执行(可以理解为子线程),可以做耗时的工作
protected Result doInBackground(Params... params){return null;}可以接收到doInBackground返回数据
4.复写其方法抽象方法,在异步任务(也就是doInBackground方法)执行之后,执行该方法,在主线程执行
protected void onPostExecute(Void result) {super.onPostExecute(result);}
5.开启一个异步任务,在主线程里新建继承了AsyncTask自定义的类,调用execute()方法.
new myAsyncTasK().execute();//execute()方法一定要用,相当于开启线程的start,调了1个小时的bug.
关于AsyncTask参数的说明
1.类中的三个泛型:
params:第一个泛型,就是5.execute方法的参数类型(其实就是他传的实际参数),也是3.doInBackground方法的参数类型
提示:3.doInBackground(Params... params){内部使用时,params就是对应类型的数组,Prarms[0]就是第一个Params}
Progress:第二个泛型,就是publishProgress(必须在3.doInBackground方法里调用)方法的参数类型,他负责发布进度,类似进度条,
也是onProgressUpdate方法的参数类型,他得到的是来自publishProgress的实际参数,进度更新时调用,在主线程中执行,可更新UI
提示:使用到第二个泛型,就要使用到publishProgress,并继续使用到onProgressUpdate(此方法要复写,具体格式如下:)
protected void onProgressUpdate(Progress... values){super.onProgressUpdate(values);}//alues就是对应类型的数组
Result:第三个泛型,既是3.doInBackground的返回值类型,并且它还是OnPostExecute的参数类型;
应用场景:在子线程(doInBackground)获取信息,在OnpostExcute里去显示;
示例代码:
public class MainActivity extends Activity { private ProgressDialog pd; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);// 开启一个异步任务,在主线程里新建继承了AsyncTask自定义的类,调用execute()方法. new myAsyncTasK().execute("www.dslkfja.com"); } public class myAsyncTasK extends AsyncTask<String,Integer,ArrayList<String>>{// 在异步任务执行之前,执行该方法,在主线程执行 protected void onPreExecute() { System.out.println(Thread.currentThread().getName()+" "+"onPreExecute在工作"); super.onPreExecute(); pd = new ProgressDialog(MainActivity.this); pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pd.setMax(10); pd.show(); }// 该方法在后台执行(可以理解为子线程),可以做耗时的工作 protected ArrayList<String> doInBackground(String... params) { System.out.println("网站是"+params[0]); SystemClock.sleep(1000); System.out.println(Thread.currentThread().getName()+" "+"doInBackground在后台忙碌"); for (int i = 0; i <10; i++) {// 发布进度 publishProgress(i); } ArrayList<String> al=new ArrayList<String>(); al.add("aaa"); al.add("vvv"); al.add("ccc"); return al; } // 进度更新时调用,在主线程中执行,所以可以更新UI protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); pd.setProgress(values[0]); System.out.println(Thread.currentThread().getName()+"我是onProgressUpdate"+values[0]); }// 在异步任务执行之后,执行该方法,在主线程执行 protected void onPostExecute(ArrayList<String> result) { pd.dismiss(); super.onPostExecute(result); System.out.println(result); System.out.println(Thread.currentThread().getName()+" "+"onPostExecute在清理着垃圾"); Toast.makeText(getApplicationContext(), "进度条完成",0).show(); } }}
- Android中AsyncTask(异步任务,实际就和handler的作用差不多)
- Android中实现异步任务机制的方式:Handler、AsyncTask
- Android中AsyncTask(异步任务)和Handler(线程消息机制)的详解
- Android异步任务:AsyncTask 和 Handler+Message详解
- [Android]关于Handler和Looper/AsyncTask异步任务
- android中异步任务AsyncTask的应用和工作原理
- Android中异步任务AsyncTask的使用
- Android中使用Handler和AsyncTask进行异步操作
- android的异步任务AsyncTask
- 安卓(Android)中如何优雅的 创建/执行 异步任务/回调(AsyncTask 、Thread、Job、CallBack、Handler) ?线程池(Executor)
- android中两种实现异步操作的方法,Handler和asynctask
- handler和异步AsyncTask
- Android中Handler和AsyncTask
- Android开发中AsyncTask实现异步处理任务的方法
- Android中AsyncTask(异步执行任务)的使用
- Android开发中AsyncTask实现异步处理任务的方法
- Android开发中AsyncTask实现异步处理任务的方法
- Android中异步任务机制AsyncTask的理解
- DIV水平,垂直方向都居中于浏览器
- Android程序员学习iOS
- input标签submit属性,用CSS控制样式时高度不好控制的解决办法
- JackSon转换Java的Json使用方法
- cygwin编译paho.mqtt.c-1.1.0
- Android中AsyncTask(异步任务,实际就和handler的作用差不多)
- angular仿支付宝密码框
- 21. Merge Two Sorted Lists
- phpMyAdmin-高级功能尚未完全设置
- 我的WCF之旅 (11): 再谈WCF的双向通讯-基于Http的双向通讯 V.S. 基于TCP的双向通讯
- WINDO查看端口 是否被占用
- 《响应式Web设计-HTML5和CSS3实战》阅读笔记第三章
- 自己常用的linux命令
- DevOps和容器:本地or云端,如何选择?