常见的多线程方法有:

  1. 继承Thread类
  2. 实现Runnable接口
  3. Handler
  4. AsyncTask
  5. HandlerThread

1.定义

  • 一个Android已经封装好的轻量级异步类
  • 属于抽象类,即使用时需要实现的子类
public abstract class AsyncTask<Params, Progress, Result> {
...
}

2.作用

  1. 实现多线程

    在工作线程中执行任务,如耗时任务。
  2. 异步通信,消息传递

    实现工作线程和主线程之间的通信,即将工作线程的执行结果传递给主线程,从而在主线程中执行相关的UI操作,从而保证线程安全。

3. 优点

  • 方便实现异步通信:

    不需要使用“任务线程(如继承Thread类)+Handler“的复杂组合
  • 节省资源:

    采用线程池的缓存线程+复用线程,避免了频繁创建&销毁线程所带来的系统资源开销。

4.类和方法

4.1类的定义

AsyncTask类术语抽象类,即使用时需要实现子类

public abstract class AsyncTask<Params, Progress, Result> {
...
} // 类中参数为3种泛型类型
// 整体作用:控制AsyncTask子类执行线程任务时各个阶段的返回类型
// 具体说明:
// a. Params:开始异步任务执行时传入的参数类型,对应excute()中 // b. Progress:异步任务执行过程中,返回下载进度值的类型
// c. Result:异步任务执行完成后,返回的结果类型,与doInBackground()的返回值类型保持一致
// 注:
// a. 使用时并不是所有类型都被使用
// b. 若无被使用,可用java.lang.Void类型代替
// c. 若有不同业务,需额外再写1个AsyncTask的子类
}

4.2核心方法

核心方法如下:

方法的执行顺序:

5.使用步骤

  1. 创建AsyncTask子类并根据需要实现核心方法
  2. 创建AsyncTask子类的实例对象
  3. 手动调用execute()从而执行异步线程任务
/**
* 步骤1:创建AsyncTask子类
* 注:
* a. 继承AsyncTask类
* b. 为3个泛型参数指定类型;若不使用,可用java.lang.Void类型代替
* c. 根据需求,在AsyncTask子类内实现核心方法
*/ private class MyTask extends AsyncTask<Params, Progress, Result> { .... // 方法1:onPreExecute()
// 作用:执行 线程任务前的操作
// 注:根据需求复写
@Override
protected void onPreExecute() {
...
} // 方法2:doInBackground()
// 作用:接收输入参数、执行任务中的耗时操作、返回 线程任务执行的结果
// 注:必须复写,从而自定义线程任务
@Override
protected String doInBackground(String... params) { ...// 自定义的线程任务 // 可调用publishProgress()显示进度, 之后将执行onProgressUpdate()
publishProgress(count); } // 方法3:onProgressUpdate()
// 作用:在主线程 显示线程任务执行的进度
// 注:根据需求复写
@Override
protected void onProgressUpdate(Integer... progresses) {
... } // 方法4:onPostExecute()
// 作用:接收线程任务执行结果、将执行结果显示到UI组件
// 注:必须复写,从而自定义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();

6.具体实例

public class MainActivity extends AppCompatActivity {

    // 线程变量
MyTask mTask; // 主布局中的UI组件
Button button,cancel; // 加载、取消按钮
TextView text; // 更新的UI组件
ProgressBar progressBar; // 进度条 /**
* 步骤1:创建AsyncTask子类
* 注:
* a. 继承AsyncTask类
* b. 为3个泛型参数指定类型;若不使用,可用java.lang.Void类型代替
* 此处指定为:输入参数 = String类型、执行进度 = Integer类型、执行结果 = String类型
* c. 根据需求,在AsyncTask子类内实现核心方法
*/
private class MyTask extends AsyncTask<String, Integer, String> { // 方法1:onPreExecute()
// 作用:执行 线程任务前的操作
@Override
protected void onPreExecute() {
text.setText("加载中");
// 执行前显示提示
} // 方法2:doInBackground()
// 作用:接收输入参数、执行任务中的耗时操作、返回 线程任务执行的结果
// 此处通过计算从而模拟“加载进度”的情况
@Override
protected String doInBackground(String... params) { try {
int count = 0;
int length = 1;
while (count<99) { count += length;
// 可调用publishProgress()显示进度, 之后将执行onProgressUpdate()
publishProgress(count);
// 模拟耗时任务
Thread.sleep(50);
}
}catch (InterruptedException e) {
e.printStackTrace();
} return null;
} // 方法3:onProgressUpdate()
// 作用:在主线程 显示线程任务执行的进度
@Override
protected void onProgressUpdate(Integer... progresses) { progressBar.setProgress(progresses[0]);
text.setText("loading..." + progresses[0] + "%"); } // 方法4:onPostExecute()
// 作用:接收线程任务执行结果、将执行结果显示到UI组件
@Override
protected void onPostExecute(String result) {
// 执行完毕后,则更新UI
text.setText("加载完毕");
} // 方法5:onCancelled()
// 作用:将异步任务设置为:取消状态
@Override
protected void onCancelled() { text.setText("已取消");
progressBar.setProgress(0); }
} @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // 绑定UI组件
setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button);
cancel = (Button) findViewById(R.id.cancel);
text = (TextView) findViewById(R.id.text);
progressBar = (ProgressBar) findViewById(R.id.progress_bar); /**
* 步骤2:创建AsyncTask子类的实例对象(即 任务实例)
* 注:AsyncTask子类的实例必须在UI线程中创建
*/
mTask = new MyTask(); // 加载按钮按按下时,则启动AsyncTask
// 任务完成后更新TextView的文本
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { /**
* 步骤3:手动调用execute(Params... params) 从而执行异步线程任务
* 注:
* a. 必须在UI线程中调用
* b. 同一个AsyncTask实例对象只能执行1次,若执行第2次将会抛出异常
* c. 执行任务中,系统会自动调用AsyncTask的一系列方法:onPreExecute() 、doInBackground()、onProgressUpdate() 、onPostExecute()
* d. 不能手动调用上述方法
*/
mTask.execute();
}
}); cancel = (Button) findViewById(R.id.cancel);
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 取消一个正在执行的任务,onCancelled方法将会被调用
mTask.cancel(true);
}
}); } }

Android多线程--AsyncTask的更多相关文章

  1. android多线程-AsyncTask之工作原理深入解析(下)

    关联文章: Android 多线程之HandlerThread 完全详解 Android 多线程之IntentService 完全详解 android多线程-AsyncTask之工作原理深入解析(上) ...

  2. android多线程-AsyncTask之工作原理深入解析(上)

    关联文章: Android 多线程之HandlerThread 完全详解 Android 多线程之IntentService 完全详解 android多线程-AsyncTask之工作原理深入解析(上) ...

  3. Android 多线程----AsyncTask异步任务详解

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...

  4. android 多线程 AsyncTask 下载图片

    AsyncTask 下载图片 package com.test.network; import android.graphics.Bitmap; import android.graphics.Bit ...

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

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

  6. Android多线程----异步消息处理机制之Handler详解

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

  7. Android多线程编程之AsyncTask

    进程?线程? 进程是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态的概念.每个进程都有自己的地址空间(进程空间).进程空间的大小与处理机位数有关.进程至少有5种基本状态:初始态,执行态 ...

  8. Android多线程分析之五:使用AsyncTask异步下载图像

    Android多线程分析之五:使用AsyncTask异步下载图像 罗朝辉 (http://www.cnblogs.com/kesalin) CC 许可,转载请注明出处 在本系列文章的第一篇<An ...

  9. Android多线程任务优化1:探讨AsyncTask的缺陷

     AsyncTask还有别的缺陷,在生成listview的时候,如果adapter里面的count动态改变的话,不能使用AsyncTask,只能使用Thread+Handler,否则会出现如下错误 j ...

随机推荐

  1. Oracle 存储过程中的临时表数据自动清空

    问题叙述: 用 EXECUTE IMMEDIATE 动态往临时表插入数据,跟踪发现插入临时表后数据会立马清空,按理说等存储过程执行完才会清空临时表才对,现在是执行插入语句后下一步验证就发现临时表就没有 ...

  2. Nginx详细介绍

    1.Nginx是什么? Nginx就是反向代理服务器. 首先我们先来看看什么是代理服务器,代理服务器一般是指局域网内部的机器通过代理服务发送请求到互联网上的服务器,代理服务器一般作用于客户端.比如Go ...

  3. .NET 开源工作流: Slickflow流程引擎高级开发(七)--消息队列(RabbitMQ)的集成使用

    前言:工作流流程过程中,除了正常的人工审批类型的节点外,事件类型的节点处理也尤为重要.比如比较常见的事件类型的节点有:Timer/Message/Signal等.本文重点阐述消息类型的节点处理,以及实 ...

  4. 键盘鼠标(PS2)模拟器驱动及Demo

    详情 KeyboardMouseSimulateDriver 问题描述: 鼠标相对移动存在不正确性,绝对移动没正确性. 基于于Thinkpad E460上的开发及测试. 不支持HID设备.

  5. (私人收藏)红色项目工作计划总结汇报PPT模板

    红色项目工作计划总结汇报PPT模板 https://pan.baidu.com/s/1fr-PB7ieveSIqSXrB0YXsgbgdc

  6. 转载------一小时包教会 —— webpack 入门指南

    本文写的蛮好,转载地址:http://www.w2bc.com/Article/50764 其他的地址: http://webpack.github.io/docs/usage-with-gulp.h ...

  7. HDU 5969 最大的位或 题解

    题目 B君和G君聊天的时候想到了如下的问题. 给定自然数l和r ,选取2个整数\(x,y\)满足\(l <= x <= y <= r\),使得\(x|y\)最大. 其中\(|\)表示 ...

  8. 记录一下安装hexo的过程

    记录一下安装hexo的过程 首先你的电脑需要安装node.js和Git 安装好Git之后需要配置本机与Github之间的ssh方便更新同步博客到Github上,在一个地方新建一个文件夹作为我们博客的根 ...

  9. python positional argument follows keyword argument

    关键字参数必须跟随在位置参数后面! 因为python函数在解析参数时, 是按照顺序来的, 位置参数是必须先满足, 才能考虑其他可变参数.

  10. python面试题三:Python 网络编程与并发

    1 简述 OSI 七层协议. OSI七层协议模型主要是: 应用层(Application):为用户的应用程序(例如电子邮件.文件传输和终端仿真)提供网络服务. 表示层(Presentation):使用 ...