[转]Android:异步处理之AsyncTask的应用(二)

2014-11-07    
既然UI老人家都这么忙了,我们这些开发者肯定不能不识趣的去添乱阻塞UI线程什么的,否则UI界面万一停止响应了呢——这不是招骂的节奏么?!所以我们知道用Handler+Thread的方法,在子线程中处理耗时的任务,任务完成后通过Handler通知UI主线程更新UI界面,皆大欢喜有木有。

  可是这样,还是有某些人觉得用Handler+Thread的代码会比较繁琐,当然这个某些人里面包括我们伟大的谷歌。所以AsyncTask(异步任务)在Android 1.5中横空出世;相对于Handler来说,由于比较好的封装,AsyncTask显得更加轻量级一点,适用于简单的异步处理;当然使用起来也比较简洁,果然是谷歌的亲儿子!

概述

  AsyncTask是一个抽象类,通常是被继承的命。AsyncTask的内部会维持一个静态的线程池,每个后台任务自然也会被提交到线程池中运行,同时也使用Handler+Thread的机制来调用AsyncTask的各个回调方法;回调方法是在主线程运行的,所以该干什么我们都懂(~ o ~)~zZ(赶紧跟UI界面套近乎呀)。

我们知道AsyncTask<Params, Progress, Result>是抽象类,我们可以在这里面看出它支持三种泛型:

1、Params:我们的AsyncTask要开始干活时,我们给他的输入的参数的类型,也就是传递给后台的参数

2、Progress:AsyncTask向我们报告它干活进度的参数类型,举个例子就是下载进度的百分比

3、Result:后台执行任务完成,返回的结果的参数类型

如果某个泛型我们不需要指定,我们可以大大方方的指定Void,没事AsyncTask不会伤心滴。

当然谷歌也帮我们将AsyncTask的后台任务运行的五种状态,分别是:1、准备运行,2、正在后台运行,3、进度更新,4、完成后台任务,5、取消任务。每种状态在AsyncTask中各有相应的回调方法。

1、准备运行:onPreExecute(),在任务开启时该回调方法立即在UI线程中被调用,同时也是在执行后台耗时操作前被调用;通常该方法用于完成一些初始化工作,比如在界面上显示进度条等。

2、正在后台运行:doInBackground(Params...),该回调函数由后台线程在onPreExecute()方法执行结束后立即调用,重写该方法就是后台线程将要完成的耗时任务;由于是由后台线程调用,所以我们不能直接在这里更新UI界面,应该使用publishProgress(Progress...)触发回调方法onProgressUpdate(Progress...)进行进度更新;任务计算的结果必须由该函数返回,并被传递到onPostExecute()中。

3、进度更新:onProgressUpdate(Progress...),在doInBackground()中调用publishProgress()方法更新任务的执行进度,将会在主线程中触发该方法,一般用于动态地显示一个进度条。

4、完成后台任务:onPostExecute(Result),当doInBackground()完成后,系统会自动调用onPostExecute()方法,并将doInBackground()的返回值传递给该方法。

5、取消任务:onCancelled (),在调用AsyncTask的cancel()方法时调用。

案例

参考代码:

复制代码

public class MainActivity extends ActionBarActivity implements OnClickListener{

private Button startdownload;

private ProgressBar probar;

private TextView tv;

private DownTask task;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

startdownload = (Button) findViewById(R.id.startdownload);

probar = (ProgressBar) findViewById(R.id.probar);

tv = (TextView) findViewById(R.id.tv);

startdownload.setOnClickListener(this);

}

@Override

public void onClick(View v) {

task = new DownTask();//同一个AsyncTask的execute只能调用一次

        task.execute("输入参数,可为空");//调用execute后将会回调onPreExecute方法

}

class DownTask extends AsyncTask<String, Integer, String>{

@Override//该方法非在主线程运行,可进行耗时操作,不可更新UI界面,其他方法为主线程运行

protected String doInBackground(String... params) {//params为execute输入的参数

for(int i = 1; i <= 100; i++){

try {//模拟下载操作

Thread.sleep(333);

publishProgress(i);//传递参数i并触发onProgressUpdate回调方法

} catch (InterruptedException e) {

e.printStackTrace();

}

}

String result = "任务已完成";

return result;//将调用onPostExecute,并将result传给该回调方法

}

@Override

protected void onPreExecute() {//该回调方法执行完毕后,将会调用doInBackground

probar.setMax(100);

probar.setProgress(0);

tv.setText("开始下载");

}

@Override

protected void onPostExecute(String result) {//doInBackground结束后回调该方法,结束。

Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();

tv.setText("下载完成");

}

@Override

protected void onProgressUpdate(Integer... values) {//通知UI界面更新

probar.setProgress(values[0]);

}

}

}

复制代码

布局文件:

复制代码

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

<Button

android:id="@+id/startdownload"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="开始下载"/>

<ProgressBar

android:id="@+id/probar"

android:layout_width="match_parent"

android:layout_height="wrap_content"

style="@android:style/Widget.ProgressBar.Horizontal"

/>

<TextView

android:id="@+id/tv"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textColor="#000000"

android:textSize="20sp"

/>

</LinearLayout>

复制代码

代码讲解:

1、点击Button后先实例化一个AsyncTask的继承子类,此时将会创建一个task。接下来变执行execute(params)方法启动异步任务。(同一个AsyncTask的实例只能执行execute一次,多次执行会抛出错误)。

2、在execute()被执行后,将会触发onPreExecute()回调方法,设置进度条的初始属性。在onPreExecute()执行完毕后,将会在后台线程开始执行doInBackground(params),该方法接收execute传入的参数,进行耗时操作,这里是模拟网络文件下载任务。

3、doInBackground()在后台线程运行中,如果需要与UI主线程交互更新进度,可以调用publishProgress(values)方法,将会触发位于UI主线程运行的onProgressUpdate(values)的回调方法,代码中在这里更新进度条的进度。

4、 当后台任务执行完成后,调用onPostExecute(Result),传入的参数是doInBackground()中返回的对象。

注意事项

1、不要在同一个AsyncTask实例中多次执行execute(),正确的方法是new一个AsyncTask执行一次execute()。

2、耗时任务一定要在doInBackground()中处理,不要在其他回调方法中处理耗时任务以免引起UI主线程的阻塞。

3、不要再doInBackground()中更新UI界面,应该通过publishProgress()调用回调方法更新UI。

4、onCancelled()只能触发AsyncTask的cancel()方法,并无法取消正在线程池运行的线程任务,但可以通过标志位来停止线程任务。

5、在不同的android版本中,AsyncTask多任务运行,有些是可以并行有些则是顺序执行,不过在高版本Android中,可以通过指定参数设置线程池执行规则。

6、AsyncTask适合处理短时间的操作,长时间的操作,比如下载一个很大的视频,这就需要你使用自己的线程来下载,不管是断点下载还是其它的。

时间: 2024-10-01 03:31:21

[转]Android:异步处理之AsyncTask的应用(二)的相关文章

Android异步处理框架AsyncTask源码解析

一.概述 在Android开发中,我们进行异步处理一般会采用两种方式: 1.Thread +Handler 通常我们在Thread里面发送消息,然后在Handler的handleMessage方法里面去处理对应的任务,因为Android是不允许UI线程去更新UI的,这个时候我们可以采取这种方式 2.AsyncTask AsyncTask是Android为我们封装的一个轻量级的异步处理框架,其实底层也是用了类似Thread+Handler的方式.对外提供了一些方法,我们实现这些方法就可以很方便的进

Android异步任务处理框架AsyncTask源码分析

[转载请注明出处:http://blog.csdn.net/feiduclear_up CSDN 废墟的树] 引言 在平时项目开发中难免会遇到异步耗时的任务(比如最常见的网络请求).遇到这种问题,我们可以自己通过Handler+Message+Thread/ThreadPool来构造一个异步耗时任务框架.当你下次项目中又遇到一个网络请求,你又不得不重写异步耗时任务处理框架.出于避免开发者重复搬砖工作,Google工程师给开发者搭建了一个通用的异步耗时任务处理框架--AsyncTask. Asyn

Android异步加载AsyncTask详解

最近项目发现个重大问题,结果打log跟踪查是AsyncTask导致的.如果对AsyncTask了解的不够深入透彻,那写代码就是埋雷.以后不定在哪个时间爆炸.首先我们要了解,谷歌为什么发明AsyncTask,AsyncTask到底是用来解决什么问题的?Android有一个原则---单线程模型的原则:UI操作并不是线程安全的并且这些操作必须在UI线程中执行. 在单线程模型中始终要记住两条法则: 1. 不要阻塞UI线程 2. 确保只在UI线程中访问Android UI工具包 首先来说说AsyncTas

android异步加载AsyncTask

http://blog.csdn.net/abc5382334/article/details/17097633 http://keeponmoving.iteye.com/blog/1515611 http://www.cnblogs.com/suinuaner/archive/2013/04/11/android_fifty.html http://blog.csdn.net/lanjianhun/article/details/8675299 http://blog.csdn.net/al

Android异步框架RxJava 1.x系列(二) - 事件及事件序列转换原理

前言 在介绍 RxJava 1.x 线程调度器之前,首先引入一个重要的概念 - 事件序列转换.RxJava 提供了对事件序列进行转换的支持,这是它的核心功能之一. 正文 1. 事件序列转换定义 所谓转换,就是将事件序列中的对象或整个序列进行加工处理,转换成不同的事件或事件序列,有点类似 Java 1.8 中的流处理. 2. 事件序列转换API 首先看一个 map() 的例子: Observable.just("images/logo.png") // 输入类型 String .map(

Android异步加载全解析之使用AsyncTask

Android异步加载全解析之使用AsyncTask 概述 既然前面提到了多线程,就不得不提到线程池,通过线程池,不仅可以对并发线程进行管理,更可以提高他们执行的效率,优化整个App.当然我们可以自己创建一个线程池,不过这样是很烦的,要创建一个高效的线程池还是挺费事的,不过,Android系统给我吗提供了AsyncTask这样一个类,来帮助我们快速实现多线程开发,它的底层实现,其实就是一个线程池. AsyncTask初探 AsyncTask,顾名思义就是用来做异步处理的.通过AsyncTask,

Android异步消息处理机制(3)asyncTask基本使用

本文翻译自android官方文档,结合自己测试,整理如下. 概述 AsyncTask抽象类,翻译过来就是异步任务,能够合理并方便的使用UI线程.该类可以实现将后台操作结果显示在UI线程中,而不需要我们自己实现子线程或者handler(当然它内部也是借助这两者实现的). 虽然AsyncTask可以提供后台运行并将结果显示在UI上,但是理想情况应该是后台操作最多只能是几秒钟,若要执行长时间的操作强烈建议使用java中的Executor,ThreadPoolExecutor,FutureTask等.

Android:异步处理之AsyncTask的应用(二)

前言 在上一篇文章中<Android:异步处理之Handler+Thread的应用(一)>,我们知道Android的UI主线程主要负责处理用户的按键事件.用户的触屏事件以及屏幕绘图事件等:既然UI老人家都这么忙了,我们这些开发者肯定不能不识趣的去添乱阻塞UI线程什么的,否则UI界面万一停止响应了呢——这不是招骂的节奏么?!所以我们知道用Handler+Thread的方法,在子线程中处理耗时的任务,任务完成后通过Handler通知UI主线程更新UI界面,皆大欢喜有木有. 可是这样,还是有某些人觉

android异步类AsyncTask的简单使用

Android为了降低这个开发难度,提供了AsyncTask.AsyncTask就是一个封装过的后台任务类,顾名思义就是异步任务,更通俗地说就是一个执行后台任务的线程 而且他还会自动通知主线程更新UI 优点: 结构清晰,容易理解. 缺点 代码量稍大 下面直接看代码 1 private class AsyncLogin extends AsyncTask<Void,Integer,Boolean>{ 2 private EditText passwordEdit; 3 private EditT