1. Thread 基本使用

Java 中可以使用 Thread 对象来处理异步逻辑:

Thread thread = new Thread(new Runnable() {@overridepublic void run(){// logic code...}});
thread.start();

但是使用 Thread 时需要处理的逻辑比较复杂,比如:

  1. 线程的创建和释放;
  2. 线程的开启和停止;
  3. 线程池管理;

所以,类似于 iOS 中也一般不适用 NSThread,在 Android 中一般也不使用 Thread 对象来处理一步逻辑,因为封装度不够,实用性太差;

2. AsynTask

使用步骤:

  1. 创建一个类,继承自 AsyncTask;
  2. 设置 AsyncTask 的第一个参数,表示参数类型。不能使用 java 原始数据类型,比如 int、char,要使用对象类型,比如 String、Integer、model,当然也可以使用 Void 来表示无参数;
  3. 第二个参数表示进度,即向外界传递出去的数据类型,即 onProgressUpdate 方法中的入参类型;
  4. 第三个参数表示返回数据的类型;
  5. 创建并调用 execute(param)方法;

AsyncTask 中方法的含义:

  1. onPreExcute:线程任务执行之前,进行一些初始化操作;
  2. OnPostExcute:线程任务执行完毕之后,做一些清除的工作,比如数据库连接。入参类型和方法中的返回参数类型相对应,可以获取到线程任务的执行结果;
  3. doInBackground:唯一一个在异步线程执行的方法,异步代码需要写在该方法中;
  4. publishProgress:可以使用在 doInBackground 中,实时向外界(主线程)传送任务的执行进度;
  5. onProgressUpdate:调用 publishProgress 方法后可以在该方法中获取进度的回调,进而可以执行一些 UI 操作;
  6. onPostExecute:任务执行完毕,即 doInBackground 执行完毕后该方法会被调用,且 doInBackground 中 return 的值会被传递到该方法中;

示例代码如下:

public class MainActivity extends AppCompatActivity {MainAsyncTask asyncTask;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);asyncTask = new MainAsyncTask();// 入参会被传递到doInBackground方法中,可以传递多个值asyncTask.execute(100);}@Overrideprotected void onDestroy() {super.onDestroy();if (asyncTask != null) {asyncTask.cancel(true);}}public class MainAsyncTask extends AsyncTask<Integer,Integer,String> {TextView textView;@Overrideprotected void onPreExecute() {super.onPreExecute();// 该方法在线程任务开始执行之前被调用textView = findViewById(R.id.textView);}@Overrideprotected String doInBackground(Integer... integers) {// 只有该方法在子线程执行,所以耗时逻辑需要在这里实现for (int i = 0; i < integers[0]; i++) {// 将当前任务的进度传递出去,这里可以传递多个值publishProgress(i);// 模拟耗时SystemClock.sleep(100);}return "Task Finished";}@Overrideprotected void onProgressUpdate(Integer... values) {super.onProgressUpdate(values);// 该方法会接收到publishProgress中传递的进度// values数组元素个数和publishProgress传递的个数一样textView.setText("loading:" + values[0] + "%......");}@Overrideprotected void onPostExecute(String s) {super.onPostExecute(s);// 任务执行完毕,即doInBackground方法return,之后会调用该方法,入参为doInBackground方法return的值textView.setText(s);}}
}

特别注意:

  • 只有 doInBackground 方法在其他线程执行,剩余方法都是在 UI 线程执行;

因此,可以直接在 onProgressUpdate 或者是 onPostExecute 方法中进行 UI 操作;

3. AsyncTask中内存泄漏的处理

当 Activity 被 Destory 时,需要主动 cancle 对应的 AsyncTask,否则会造成内存泄漏,需要在 onDestroy 方法中主动清除:

@Override
protected void onDestroy() {super.onDestroy();if (asyncTask != null) {if (!asyncTask.isCancelled()) {asyncTask.cancel(true);}}
}

PS:有资料说即使 cancel 方法的参数 mayInterruptIfRunning 为 True,AsyncTask 也不会中断,此时需要在 doInBackground 中加入 while() 判断:

@Override
protected String doInBackground(Integer... integers) {// 只有该方法在子线程执行,所以耗时逻辑需要在这里实现while(!this.isCancelled()){for (int i = 0; i < integers[0]; i++) {// 将当前任务的进度传递出去,这里可以传递多个值publishProgress(i);// 模拟耗时SystemClock.sleep(100);}}return "Task Finished";
}

当然,还可以将 AsyncTask 标记为 static,此时内部类变成了静态内部类。Java 中 文档中指出,一旦内部类使用static修饰,那么此时这个内部类就升级为顶级类。所以,从某种意义上说,静态内部类已经不是内部类的一种了。所以:

  1. 静态内部类不能再使用外部类中的实例方法、属性;
  2. 本质是静态内部类不再引用外部类了,因此也不存在 Activity 无法被释放的情况,也就不会造成内存泄漏,最多就是 Activity 被回收,AsyncTask 仍在执行;

4. 为什么 AsyncTask 会内存泄漏

AsyncTask之所以可能会产生内存泄露,是因为:

  1. 我们一般在组件内部,以内部类的方式创建AsyncTask,而java里面,内部类是默认持有外部类的引用。
  2. 我们的加载数据是在子线程中执行,但是java里面有没有提供很好的中断机制来中断线程 (有中断方法,但是如果你不针对性的处理,这个方法也没什么卵用),这样就导致组件生命周期已经结束,应该被GC回收,但是由于子线程正在执行,内部类无法回收,进而导致组件无法正常回收,所以造成了内存泄露 (Handler导致内存泄露也是类似的道理)。

来源:Android 中更安全的使用 AsyncTask


http://www.taodudu.cc/news/show-1912746.html

相关文章:

  • 在Nginx中配置SSL证书
  • Base64编码流程
  • Nginx配置基础认证
  • Cookie、Session、Token、RefreshToken
  • JSCore浅析及其在iOS上的使用
  • 编程语言的动态性(Dart和OC对比)
  • iOS:Universal Link
  • AFN中的鉴权
  • openGL ES 教程(二):渲染管线
  • MySQL(2)----DDL语句之增、删、改、查操作
  • MySQL(3)-----DML数据库操作(上)
  • 线性表的基本运算
  • MySQL(4)-----DML数据库操作(下)
  • MySQL(1)----帮助使用
  • MySQL(6)-----数据类型
  • (1)封装JSON数据的三种方式
  • (2)从文件中解析JSON数据
  • (1)I/O流对象-----FileInputStream与FileOutputStream
  • MyBatis(一)------目录
  • MyBatis(二)------使用JDBC编程问题总结
  • MySQL(5)-----DQL语句的基本查询与高级查询
  • MySQL(7)-----常用约束
  • MySQL(8)-----truncate清空表和字段自增
  • MySQL(9)-----多表创建及描述表关系(需求)
  • (1)Spring框架----通俗易懂的IoC原理
  • MySQL(10)-----多表创建及描述表关系(一对多的分析和实现)
  • MySQL(11)-----多表创建及描述表关系(多对多的分析和实现)
  • MySQL(12)-----多表查询(内连接和外连接)
  • MySQL(13)-----多表查询(子查询)
  • MySQL(14)-----运算符和优先级

AsyncTask的基本使用相关推荐

  1. android asynctask源码分析,Android通过Handler与AsyncTask两种方式动态更新ListView(附源码)...

    本文实例讲述了Android通过Handler与AsyncTask两种方式动态更新ListView的方法.分享给大家供大家参考,具体如下: 有时候我们需要修改已经生成的列表,添加或者修改数据,noti ...

  2. 【Android】AsyncTask异步类

    一.关于AysncTask AsyncTask使得多线程编程更加简单,AsyncTask能在后台线程执行异步任务,并且在UI线程更新界面,而不再需要用户去操作Thread和Handler.AysncT ...

  3. Asynctask源码分析

    ​ 首先我们使用AsyncTask时,一般是: new AsyncTask(...).execute() 复制代码 我们看new AsyncTask(),它走的是: public AsyncTask( ...

  4. Android 多线程-----AsyncTask详解

    您可以通过点击 右下角 的按钮 来对文章内容作出评价, 也可以通过左下方的 关注按钮 来关注我的博客的最新动态. 如果文章内容对您有帮助, 不要忘记点击右下角的 推荐按钮 来支持一下哦 如果您对文章内 ...

  5. android一个简单的异步AsyncTask下载数示例,简单下载(07)

    2019独角兽企业重金招聘Python工程师标准>>> public class MainActivity extends Activity {private ImageView i ...

  6. Android 消息异步处理之AsyncTask

    Android提供了异步处理消息的方式大致有两种,第一种是handler+Thread,之前已经对于这种方式做过分析,第二种就是AsyncTask,这是Android1.5提供的一种轻量级的工具类,其 ...

  7. Android 学习笔记--android——AsyncTask在Android4.X的机制问题

    AsyncTask在Android4.X的机制问题 AsyncTask在Android4.X机制是串行的...单一AsyncTask运行完才会运行下一个 AsyncTask在Android2.3机制是 ...

  8. AsyncTask进度条加载网站数据到ListView

    2019独角兽企业重金招聘Python工程师标准>>> 代码介绍: 初学android,写了个一小demo.功能很简单,主要是用来学习, 知识要点: 1.android全局变量的使用 ...

  9. 源码篇——AsyncTask机制

    AsyncTask new AsyncTask<String,String,String>(){// 运行在主线程中,做预备工作onPreExecute(){}// 运行在子线程中,做耗时 ...

  10. Android中 AsyncTask

    Android AsyncTask 在程序处理中必然会遇上耗时的操作,如访问网络,下载数据,访问数据库等,如何存在耗时的操作 又不能影响界面显示交互. 在某些耗时可以控制的情况下,我们可以分批操作,对 ...

最新文章

  1. 【Android 应用开发】 Android APK 反编译 混淆 反编译后重编译
  2. 为什么要用dubbo,dubbo和zookeeper关系
  3. 【leetcode】443. String Compression
  4. mysql 分类_MYSQL数据类型分类
  5. 2017 码云最火开源项目 TOP 50,你用过哪些?
  6. POS58热敏打印解决方法
  7. 固态加装机械计算机不显示,win10不显示机械硬盘怎么办_win10加装机械硬盘不显示的解决方法...
  8. 2019年安徽省大数据与人工智能应用赛总结---本科组
  9. JAVA:实现 gnome sort侏儒排序算法(附完整源码)
  10. STL(五)之智能指针剖析
  11. 【偶爱宋词】章良能·小重山
  12. 贵卅大学计算机研究生院导师,贵州大学机械工程学院研究生导师:罗绍华
  13. 《小王爱迁移》文章链接
  14. SVD的原理及python实现——正本清源
  15. TCP/IP入门详解--业内最佳
  16. 关联网页可信度分析和文本内容(IEEE2014)
  17. 2022年东南大学计算机考研复试分数线
  18. rem动态计算rem
  19. 根据证件号码(zjhm)自动显示出生日期,籍贯,户籍所在地等信息
  20. 小米2013校园招聘笔试题的第一道程序设计题

热门文章

  1. centos服务器安装docker步骤
  2. 3. 什么是icmp?icmp与ip的关系_0.3亿人口的美国会比3亿人口的美国富裕吗?
  3. Dubbo服务治理(一):限流策略
  4. 线程池Executor框架解读
  5. php 5.4中php-fpm 的重启、终止操作命令
  6. 关于EXP-00056: 遇到 ORACLE 错误 1455 ORA-01455: 转换列溢出整数数据类型 EXP-00000: 导出终止失败 的问题解决方法整理...
  7. 中国传媒大学公开课:理解人类传播
  8. Visual Studio Code如何打开多个tab标签
  9. java.lang.UnsupportedOperationException WebView is not allowed in privileged processes
  10. linux java服务,在Linux上运行Java应用程序即服务