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

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

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

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

(1)Params 启动任务执行的输入参数,比如HTTP请求的URL。   

(2)Progress 后台任务执行的百分比。   

(3)Result 后台执行任务最终返回的结果,比如String。

  2、使用过AsyncTask 最少要重写以下这两个方法:   

(1)doInBackground(Params…) 后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。

(2)onPostExecute(Result) 相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回

  另外三个方法可选,不是必须的:

(3)onProgressUpdate(Progress…) 可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。   

(4)onPreExecute() 这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。   

(5)onCancelled() 用户调用取消时,要做的操作

  3、使用AsyncTask类,以下是几条必须遵守的准则:   

(1)Task的实例必须在UI thread中创建;   

(2)execute方法必须在UI thread中调用;   

(3)不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法;   

(4)该task只能被执行一次,否则多次调用时将会出现异常;

(二)AsyncTask和Handler对比

  1、AsyncTask实现的原理,和适用的优缺点

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

  (1)使用的优点:

  A、简单,快捷;   B、过程可控。

  (2)使用的缺点:

  在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来。

  2、Handler异步实现的原理和适用的优缺点

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

  (1)使用的优点:

  A、 结构清晰,功能定义明确

  B、 对于多个后台任务时,简单,清晰

  (2)使用的缺点:

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

1、布局文件

  打开res/layout/activity_main.xml文件。   输入以下代码:

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/url"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true" >
<requestFocus />
</EditText> <Button
android:id="@+id/open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="AsyncTask处理" /> <EditText
android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textMultiLine" /> </LinearLayout> <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/url"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true" >
<requestFocus />
</EditText> <Button
android:id="@+id/open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="AsyncTask处理" /> <EditText
android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textMultiLine" /> </LinearLayout>

2.程序文件

package com.genwoxue.asynctask;   

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView; public class MainActivity extends Activity{
private EditText message;
private Button open;
private EditText url; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
message= (EditText) findViewById(R.id.message);
url= (EditText) findViewById(R.id.url);
url.setText("http://www.genwoxue.com");
open= (Button) findViewById(R.id.open);
open.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
connect();
}
});
}
private void connect() {
PageTask task = new PageTask(this);
task.execute(url.getText().toString());
} /* 四个步骤:
* (1)onPreExecute(),执行预处理,它运行于UI线程,
* 可以为后台任务做一些准备工作,比如绘制一个进度条控件。
* (2)doInBackground(Params...),后台进程执行的具体计算在这里实现,
* doInBackground(Params...)是AsyncTask的关键,此方法必须重载。
* 在这个方法内可以使用 publishProgress(Progress...)改变当前的进度值。
* (3)onProgressUpdate(Progress...),运行于UI线程。如果
* 在doInBackground(Params...) 中使用了publishProgress(Progress...),就会
* 触发这个方法。在这里可以对进度条控件根据进度值做出具体的响应。
* (4)onPostExecute(Result),运行于UI线程,可以对后台任务的结果做出处理,结果
* 就是doInBackground(Params...)的返回值。此方法也要经常重载,如果Result为
* null表明后台任务没有完成(被取消或者出现异常)。 *
*/
class PageTask extends AsyncTask<String, Integer, String> {
// 可变长的输入参数,与AsyncTask.exucute()对应
ProgressDialog pdialog;
public PageTask(Context context){
pdialog = new ProgressDialog(context, 0);
pdialog.setButton("cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int i) {
dialog.cancel();
}
}); pdialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
finish();
}
}); pdialog.setCancelable(true);
pdialog.setMax(100);
pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pdialog.show();
} // (1)任务启动
@Override
protected void onPreExecute() {
message.setText("task_started");
} //(2)后台执行:主要工作在这里实现
@Override
protected String doInBackground(String... params) {
String result = null;
try{
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(params[0]); // params[0]代表连接的url
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
long length = entity.getContentLength();
InputStream is = entity.getContent();
if(is != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[128];
int ch = -1;
int count = 0;
while((ch = is.read(buf)) != -1) {
baos.write(buf, 0, ch); count += ch;
if(length > 0) {
// 如果知道响应的长度,调用publishProgress()更新进度
publishProgress((int) ((count / (float) length) * 100));
}
Thread.sleep(50); // 让线程休眠50ms
}
result = new String(baos.toByteArray());
}
return result; // 返回结果
} catch(Exception e) {
e.printStackTrace();
}
return null;
} //(3)由doInBackground中的publishProgress(Progress...)触发onProgressUpdate这个方法
@Override
protected void onProgressUpdate(Integer... values) {
// 更新进度
System.out.println(""+values[0]);
message.setText(""+values[0]);
pdialog.setProgress(values[0]);
} //(4)可以对后台任务的结果做出处理,结果就是doInBackground(Params...)的返回值。
@Override
protected void onPostExecute(String result) {
// 返回HTML页面的内容
message.setText(result);
pdialog.dismiss();
} @Override
protected void onCancelled() {
super.onCancelled();
} }
}

3 配置文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.genwoxue.asynctask"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="15" /> <uses-permission android:name="android.permission.INTERNET"/> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.genwoxue.asynctask.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application> </manifest>

注意:需要在AndroidManifest.xml文件中添加权限:

  <uses-permission android:name="android.permission.INTERNET"/>

4运行结果

来源:www.genwoxue.com

异步处理工具类:AsyncTask的更多相关文章

  1. Android消息机制——时钟显示和异步处理工具类(AsyncTask)

    1. 时钟显示 定义布局文件——activity_my_analog_clock_thread_demo.xml <?xml version="1.0" encoding=& ...

  2. C# 异步工具类 及一点小小的重构经验

    2015年新年第一篇随笔, 祝福虽然有些晚,但诚意还在:新年快乐. 今天主要是想分享一异步工具类,在C/S架构中.先进行网络资源异步访问,然后将回调函数 Invoke到UI线程中进行UI处理. 这样的 ...

  3. 重复造轮子,编写一个轻量级的异步写日志的实用工具类(LogAsyncWriter)

    一说到写日志,大家可能推荐一堆的开源日志框架,如:Log4Net.NLog,这些日志框架确实也不错,比较强大也比较灵活,但也正因为又强大又灵活,导致我们使用他们时需要引用一些DLL,同时还要学习各种用 ...

  4. C#操作Control异步工具类

    /// <summary> /// 异步工具类 /// </summary> public class TaskTools { /// <summary> /// ...

  5. c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习

    c#中@标志的作用   参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ...

  6. Android加载网络图片的工具类

    ImageView加载网络的图片 HttpUtil.java package com.eiice.httpuimagetils; import java.io.ByteArrayOutputStrea ...

  7. Cache【硬盘缓存工具类(包含内存缓存LruCache和磁盘缓存DiskLruCache)】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 内存缓存LruCache和磁盘缓存DiskLruCache的封装类,主要用于图片缓存. 效果图 代码分析 内存缓存LruCache和 ...

  8. Android 开源控件与常用开发框架开发工具类

    Android的加载动画AVLoadingIndicatorView 项目地址: https://github.com/81813780/AVLoadingIndicatorView 首先,在 bui ...

  9. C# 超时工具类 第二版

    附源码,没有附测试demo 之前的工具类:C# 给某个方法设定执行超时时间 /// <summary> /// 超时工具 /// </summary> public class ...

随机推荐

  1. mysql 启动错误1026

    进入“事件查看器”“应用程序”果然发现很多MySql的错误Default storage engine (InnoDB) is not available 于是进入MySql的安装目录找到my.ini ...

  2. JavaScript 数组方法和属性

    一. 数组对象的操作方法 1. 数组的创建 2.prototype属性 返回对象原型的引用,prototype属性时object共有的. objectName.prototype,其中objectNa ...

  3. DotNetBar v12.7.0.2 Fully Cracked

    更新信息: http://www.devcomponents.com/customeronly/releasenotes.asp?p=dnbwf&v=12.7.0.2 如果遇到破解问题可以与我 ...

  4. VMWare三种工作模式 :bridge、host-only、nat

    VMWare提供了三种工作模式,它们是bridged(桥接模式).NAT(网络地址转换模式)和host-only(主机模式).要想在网络管理和维护中合理应用它们,你就应该先了解一下这三种工作模式.这里 ...

  5. Ubuntu 14.10 下卸载MySQL

    前面讲了Mysql的简单安装方式,通过sudo apt-get install mysql-server 等脚本,安装之后如何卸载? 1 通过下面命令删除MySQL sudo apt-get auto ...

  6. STL 源码分析《2》----nth_element() 使用与源码分析

    Select 问题: 在一个无序的数组中 找到第 n 大的元素. 思路 1: 排序,O(NlgN) 思路 2: 利用快排的 RandomizedPartition(), 平均复杂度是 O(N) 思路 ...

  7. CodeForces 56E-Domino Principle

    E - Domino Principle Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I6 ...

  8. 【LeetCode】Rotate Array

    Rotate Array Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = ...

  9. 怎样修改Response中的内容

    重写Stream public class CatchTextStream : Stream { private Stream output; public CatchTextStream(Strea ...

  10. UINavigationController的使用(多视图控制器)

    一,重点 当视图控制器控制多视图时,所有页都有导航栏,如果我们有的页面不希望有导航栏咋办?网上没有搜索到结果,我探索到之后发表于此: [super navigationController].navi ...