AsyncTask

实现原理

AsyncTask是Android提供的轻量级异步类,可以直接继承AsyncTask在类中实现异步操作,并提供接口反馈当前的异步执行程度(通过接口实现UI进度更新),最后反馈执行的结果给UI主线程。

使用优点

1.简单快捷的实现异步操作

2.过程可控

使用的缺点:

1.在使用多个异步操作并需要进行UI变更时会变得复杂

Handler

实现原理

在Handler异步实现时,涉及到Handler, Looper, Message, Thread四个对象, 实现异步的流程是主线程启动Thread(子线程) athread(子线程)运行并生成Message-aLooper获取Message并传递给Handler,逐个获取Looper中的Message,并进行UI变更。

使用优点:

1.结构清晰,功能定义明确

2.对于过个后台任务时,简单,清晰

使用缺点:

1.在单个后台异步处理时,显得代码过多,结果过于复杂(相对性)

AsyncTask介绍

Class Overview

AsyncTask的使用使UI线程更简单易用,这个类允许执行后台操作,然后把结果返回给UI线程,而不必处理thread和handlers

AsyncTask被设计为一个围绕着Thread与Handler的帮助类,不构成一个一般性的线程框架。AsyncTask应该被用在耗时不太多的操作(做多几秒)。如果你需要让线程跑很长时间的话,强烈建议你使用java.util.concurrent包里的各种API,比如Executor, ThreadPoolExecutor 和FutureTask.

一个异步任务是用来在后台线程做计算的,异步任务的结果被UI线程调用,一个异步任务被定义了3个泛型:

  1. Params
  2. Progress
  3. Result

    和四个方法:
  4. onPreExecute
  5. doInBackground
  6. onProgressUpdate
  7. onPostExecute

Android的AsyncTask比Handler更轻量级一些,适用于简单的异步处理。

首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理不可避免的。

Android为了降低这个开发难度,提供了AsyncTask。AsyncTask就是一个封装过的后台任务类,顾名思义就是异步任务。

AsyncTask直接继承于Object类,位置为android.os.AsyncTask。要使用AsyncTask工作我们要提供三个泛型参数,并重载几个方法(至少重载一个)。

AsyncTask定义了三种泛型类型 Params, Progress , Result。

  • Params 启动任务执行的输入参数,比如HTTP请求的URL。
  • Progress 后台任务执行的百分比。
  • Result 后台执行任务最终返回的结果,比如String。

使用AsyncTask,一个异步加载数据最少要Override一下两个方法:

  • doInBackground(Params...)后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress...)来更新进度。
  • onPostExecute(Result)相当于Handler处理UI的方式,在这里可以使用doInBackground得到的处理结果作为此方法的返回参数返回

有必要的话你还要使用以下三个方法,但不是必须的:

  • onProgressUpdate(Progress...)可以使用进度条增加用户体验。此方法在主线程执行,用于显示任务的执行程度。
  • onPreExecute() 这里是用户最终调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。
  • onCancelled() 用户调用取消时要做的操作

使用AsyncTask类,必须遵守准则:

  • Task的实例必须在UI thread中创建
  • execute方法必须在UI thread中调用
  • 不要手动的调用onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...)这几个方法
  • 该task只能被执行一次, 否则多次调用时将会出现异常

一个超简单的理解 AsyncTask 的例子:

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/textView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<ProgressBar
android:id="@+id/progressBar02"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal"
/>
<Button
android:id="@+id/button03"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="更新progressbar"
/>
</LinearLayout>

MainActivity.java

package vic.wong.main;  

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView; public class MainAcitvity extends Activity {
private Button button;
private ProgressBar progressBar;
private TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mian); button = (Button)findViewById(R.id.button03);
progressBar = (ProgressBar)findViewById(R.id.progressBar02);
textView = (TextView)findViewById(R.id.textView01); button.setOnClickListener(new OnClickListener(){ @Override
public void onClick(View v){
ProgressBarAsyncTask asyncTask = new ProgressBarAsyncTask(textView, progressBar);
asyncTask.execute(1000);
}
});
}
}

NetOperator.java

package vic.wong.main;
import android.os.AsyncTask;
import android.widget.ProgressBar;
import android.widget.TextView; /**
* 生成该类的对象,并调用execute方法之后
* 首先执行的是onProExecute方法
* 其次执行doInBackgroup方法
*
*/
public class ProgressBarAsyncTask extends AsyncTask<Integer, Integer, String> {
private TextView textView;
private ProgressBar progressBar;
public ProgressBarAsyncTask(TextView textView, ProgressBar progressBar){
super();
this.textView = textView;
this.progressBar = progressBar;
} /**
* 这里的Integer参数对应AsyncTask中的第一个参数
* 这里的String返回值对应AsyncTask的第三个参数
* 该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改
* 但是可以调用publishProgress方法触发onProgressUpdate对UI进行操作
*/ @Override
protected String doInBackground(Integer...params) {
NetOperator netOperator = new NetOperator();
int i = 0;
for(i = 10; i <= 100; i+=10){
netOperator.operator();
publishProgress(i);
}
return i + params[0].intValue() + "";
}
/**
* 这里的String参数对应AsyncTask中的第三个参数(也就是接收doInBackground的返回值)
* 在doInBackground方法执行结束之后在运行,并且运行在UI线程当中 可以对UI空间进行设置
*/
@Override
protected void onPostExecute(String result) {
textView.setText("异步执行结束" + result);
} //该方法运行在UI线程当中, 并且运行在UI线程当中, 可以对UI空间进行设置
@Override
protected void onPreExecute() {
textView.setText("开始执行异步线程");
}
/**
* 这里的Intege参数对应AsyncTask中的第二个参数
* 在doInBackground方法当中,,每次调用publishProgress方法都会触发onProgressUpdate执行
* onProgressUpdate是在UI线程中执行,所以可以对UI空间进行操作
*/
@Override
protected void onProgressUpdate(Integer...values){
int value = values[0];
progressBar.setProgress(value);
} }

Android Learning Note -- AsyncTask浅尝的更多相关文章

  1. Android安全开发之浅谈密钥硬编码

    Android安全开发之浅谈密钥硬编码 作者:伊樵.呆狐@阿里聚安全 1 简介 在阿里聚安全的漏洞扫描器中和人工APP安全审计中,经常发现有开发者将密钥硬编码在Java代码.文件中,这样做会引起很大风 ...

  2. 浅尝ECMAScript6

    浅尝ECMAScript6 简介 ECMAScript6 是最新的ECMAScript标准,于2015年6月正式推出(所以也称为ECMAScript 2015),相比于2009年推出的es5, es6 ...

  3. Learning note for Binding and validation

    Summary of my learning note for WPF Binding Binding to DataSet. when we want to add new record, we s ...

  4. 浅尝key-value数据库(二)——MongoDB的优与劣

    浅尝key-value数据库(二)——MongoDB的优与劣 MongoDB的名字取自英文单词"humongous"的中间五个字母,是一个C++开发的基于分布式文件存储的数据库开源 ...

  5. 浅尝key-value数据库(三)——MongoDB的分布式

    浅尝key-value数据库(三)——MongoDB的分布式 测试了单机MongoDB的随机读和写入性能,这一节来讲一讲MongoDB的分布式. MongoDB的分布式分成两种,一种是Replicat ...

  6. 浅尝key-value数据库(一)——一览NoSQL

    浅尝key-value数据库(一)——一览NoSQL 最近由于一个项目的关系,研究了一下key-value数据库这个最近很火的概念.本系列从项目需求的角度分析并测试了几个key-value数据库的性能 ...

  7. Python图形界面开发编程:wxPython(浅尝篇)

    Python 提供了多个图形开发界面的库,几个常用 Python GUI 库如下: Tkinter: Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包的接口 .Tk 和 ...

  8. 微信团队分享:Kotlin渐被认可,Android版微信的技术尝鲜之旅

    本文由微信开发团队工程是由“oneliang”原创发表于WeMobileDev公众号,内容稍有改动. 1.引言   Kotlin 是一个用于现代多平台应用的静态编程语言,由 JetBrains 开发( ...

  9. Android开发之AsyncTask的使用

    Android API 3时引进了AsyncTask,也叫异步任务.使用它可以很方便的更新主线程中的UI,使用它比Handler.Thread更简单.由于AsyncTask是抽象类,要使用它首先要创建 ...

随机推荐

  1. hash与map的区别联系应用(转)

    一,hashtable原理: 哈希表又名散列表,其主要目的是用于解决数据的快速定位问题.考虑如下一个场景. 一列键值对数据,存储在一个table中,如何通过数据的关键字快速查找相应值呢?不要告诉我一个 ...

  2. 蒟蒻的HNOI2017滚粗记

    蒟蒻的第一次省选,然而并没有RP爆发... Day 1: 8:00开考,(然而密码错误是什么鬼).跌跌撞撞,8:40终于拿到纸质试题. { T1:作为一名没有学过Splay的蒟蒻,考场上真的被出题人感 ...

  3. JRE System Library 与Java EE Libraries的区别

    JRE System Library是只要做java开发都需要的完整的.标准的库.  Java EE5 Libraries只是java三个方向中做java EE所需要的库.如果做Web方面的开发的话就 ...

  4. JQ的双向数据绑定

    把渲染页面封装在function里面 在修改后直接调用,但是如果有alert();一定要注意function的摆放位置,正常应该是在alert前面,应为如果在后面会影响重新渲染的效果

  5. 使用Pycharm官方统计代码行插件统计代码总行数

    最近有需求,需要统计项目代码的总行数,首先想到了使用Pycharm官方的统计行数插件,发现效果还不错. 官方代码统计插件指导:https://plugins.jetbrains.com/plugin/ ...

  6. laravel 自定义分页 offset 和 limit 的使用

    laravel 本身有一个自带的快速分页方法 paginate,只需要传入每页显示多少条数据就可以 了,但是如果想使用自定义从哪里开始呢,这时候就可以使用offset 和 limit 的组合,offs ...

  7. Code:zabbix 目录

    ylbtech-Code:zabbix 目录 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部     6.返回顶部   作者:ylbtech出处:http://y ...

  8. 容器vector 迭代器iterator 应用

    #include <iostream> #include <vector> using namespace std; int main() { vector<int> ...

  9. 6-8 adaboost分类器2

    重点分析了Adaboost它的分类结构,以及如何使用Adaboost.这一节课讲解Adaboost分类器它训练的步骤以及训练好之后的XML文件的文件结构.所以这节课的核心是Adaboost分类器它的训 ...

  10. HDU 5878 I Count Two Three (预处理+二分查找)

    题意:给出一个整数nnn, 找出一个大于等于nnn的最小整数mmm, 使得mmm可以表示为2a3b5c7d2^a3^b5^c7^d2​a​​3​b​​5​c​​7​d​​. 析:预处理出所有形为2a3 ...