1、对于耗时的操作,我们的一般方法是开启“子线程”。如果需要更新UI,则需要使用handler

2、如果耗时的操作太多,那么我们需要开启太多的子线程,这就会给系统带来巨大的负担,随之也会带来性能方面的问题。在这种情况下我们就可以考虑使用类AsyncTask来异步执行任务,不需要子线程和handler,就可以完成异步操作和刷新UI。

3、AsyncTask:对线程间的通讯做了包装,是后台线程和UI线程可以简易通讯:后台线程执行异步任务,将result告知UI线程。

4、使用方法:共分为两步,自定义AsyncTask,在耗时的地方调用自定义的AsyncTask。可以参照以下代码示例。

step1:继承AsyncTask<Params,Progress,Result>

Params:输入参数。对应的是调用自定义的AsyncTask的类中调用excute()方法中传递的参数。如果不需要传递参数,则直接设为Void即可。

Progress:子线程执行的百分比

Result:返回值类型。和doInBackground()方法的返回值类型保持一致。

step2:实现以下几个方法:执行时机和作用看示例代码,以下对返回值类型和参数进行说明

onPreExecute():无返回值类型。不传参数

doInBackground(Params... params):返回值类型和Result保持一致。参数:若无就传递Void;若有,就可用Params

publishProgress(Params... params):在执行此方法的时候会直接调用onProgressUpdate(Params... values)

onProgressUpdate(Params... values):无返回值类型。参数:若无就传递Void;若有,就可用Progress

onPostExecute(Result  result) :无返回值类型。参数:和Result保持一致。

step3:在调用自定义的AsyncTask类中生成对象;

执行  :对象.excute(Params... params);

小注:

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

示例代码:

<?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:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello , Welcome to Andy's Blog!"/>
<Button
android:id="@+id/download"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Download"/>
<TextView
android:id="@+id/tv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="当前进度显示"/>
<ProgressBar
android:id="@+id/pb"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal"/>
</LinearLayout>
package sn.demo;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.TextView; public class DownloadTask extends AsyncTask<Integer, Integer, String> {
//后面尖括号内分别是参数(线程休息时间),进度(publishProgress用到),返回值 类型 private Context mContext=null;
private ProgressBar mProgressBar=null;
private TextView mTextView=null;
public DownloadTask(Context context,ProgressBar pb,TextView tv){
this.mContext=context;
this.mProgressBar=pb;
this.mTextView=tv;
}
/*
* 第一个执行的方法
* 执行时机:在执行实际的后台操作前,被UI 线程调用
* 作用:可以在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化,这个方法可以不用实现。
* @see android.os.AsyncTask#onPreExecute()
*/
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
Log.d("sn", "00000");
super.onPreExecute();
} /*
* 执行时机:在onPreExecute 方法执行后马上执行,该方法运行在后台线程中
* 作用:主要负责执行那些很耗时的后台处理工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
* @see android.os.AsyncTask#doInBackground(Params[])
*/
@Override
protected String doInBackground(Integer... params) {
// TODO Auto-generated method stub
Log.d("sn", "1111111");
for(int i=0;i<=100;i++){
mProgressBar.setProgress(i);
publishProgress(i);
try {
Thread.sleep(params[0]);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return "执行完毕";
} /*
* 执行时机:这个函数在doInBackground调用publishProgress时被调用后,UI 线程将调用这个方法.虽然此方法只有一个参数,但此参数是一个数组,可以用values[i]来调用
* 作用:在界面上展示任务的进展情况,例如通过一个进度条进行展示。此实例中,该方法会被执行100次
* @see android.os.AsyncTask#onProgressUpdate(Progress[])
*/
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
Log.d("sn", "2222222222");
mTextView.setText(values[0]+"%");
super.onProgressUpdate(values);
} /*
* 执行时机:在doInBackground 执行完成后,将被UI 线程调用
* 作用:后台的计算结果将通过该方法传递到UI 线程,并且在界面上展示给用户
* result:上面doInBackground执行后的返回值,所以这里是"执行完毕"
* @see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
Log.d("sn", "3333333333"); super.onPostExecute(result);
} }
package sn.demo;

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 AsyncTaskDemoActivity extends Activity {
/** Called when the activity is first created. */
private Button download;
private TextView tv;
private ProgressBar pb;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); initView();
}
private void initView() {
// TODO Auto-generated method stub
tv=(TextView)findViewById(R.id.tv);
pb=(ProgressBar)findViewById(R.id.pb);
download=(Button)findViewById(R.id.download);
download.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
DownloadTask dt=new DownloadTask(AsyncTaskDemoActivity.this,pb,tv);
dt.execute(100);
}
});
}
}

Asynctask的使用及理解的更多相关文章

  1. 转:探讨android更新UI的几种方法

    本文转自:http://www.cnblogs.com/wenjiang/p/3180324.html 作为IT新手,总以为只要有时间,有精力,什么东西都能做出来.这种念头我也有过,但很快就熄灭了,因 ...

  2. 【转】探讨android更新UI的几种方法----不错

    原文网址:http://www.cnblogs.com/wenjiang/p/3180324.html 作为IT新手,总以为只要有时间,有精力,什么东西都能做出来.这种念头我也有过,但很快就熄灭了,因 ...

  3. Android学习笔记十:异步处理

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7520700.html 一:基础概念 UI线程:当Android程序第一次启动时,Android会同时启动一条主 ...

  4. 探讨android更新UI的几种方法

    作为IT新手,总以为只要有时间,有精力,什么东西都能做出来.这种念头我也有过,但很快就熄灭了,因为现实是残酷的,就算一开始的时间和精力非常充足,也会随着项目的推进而逐步消磨殆尽.我们会发现,自己越来越 ...

  5. 探讨android更新UI的几种方法(转)

    作为IT新手,总以为只要有时间,有精力,什么东西都能做出来.这种念头我也有过,但很快就熄灭了,因为现实是残酷的,就算一开始的时间和精力非常充足,也会随着项目的推进而逐步消磨殆尽.我们会发现,自己越来越 ...

  6. Android AsyncTask完全解析,带你从源码的角度彻底理解

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11711405 我们都知道,Android UI是线程不安全的,如果想要在子线程里进 ...

  7. 正确理解 AsyncTask,Looper,Handler三者之间的关系(基于android 4.0)

    Looper 和Handler 是理解好AsyncTask的一个基础,我们可以先从这里开始,先给出一个主线程和子线程互相通信的例子. package com.example.loopertest; i ...

  8. AsyncTask理解- Day36or37

    AsyncTask理解- Day36or37 mobile 5.0 1.手机归属地查询 AtoolsActivity Assets目录特点 该文件是原生文件,不会对里面的文件进行编码 该文件只支持读取 ...

  9. 深入理解AsyncTask的工作原理

    一.为什么需要工作者线程 我们知道,Android应用的主线程(UI 线程)肩负着绘制用户界面和及时响应用户操作的重任,为了避免“用户点击按钮后没反应”这样的糟糕用户体验,我们就要确保主线程时刻保持着 ...

随机推荐

  1. int* V.S. int[]

    [int* V.S. int[]] 在C++中,int[]有2种形态,一种是指针形态,即使用方法和int*一样,另一种是符号形态,即只是一个编译期的符号(意味着在runtime期,所定义的int[]根 ...

  2. Jsch

    JSch is a pure Java implementation of SSH2. JSch allows you to connect to an sshd server and use por ...

  3. .Net项目版本号的生成

    给.Net项目编译的程序集加入版本号的方式有许多种,包括: 1. 默认的方式,在每个项目的AssemblyInfo.cs文件中指定版本号: // Version information for an ...

  4. Unity3d:延迟加载ScrollView的内容

    问题描述:在一个scrollview中加载了大量的数据,有文字.图片.视频等等,首次加载的时候会很慢很卡,而且加载出来后,内存占用很大.解决方案1:思:固定一块区域,当物体滚动到这区域的时候再加载物体 ...

  5. 在Windows2012下安装SQL Server 2005无法启动服务的解决办法

    下面是我亲自经历过的总结. 因为尝鲜安装了Windows2012,的确很不错,唯一的遗憾就是不支持Sql Server 2005的安装.找了很多办法,基本上都有缺陷.现在终于找到一种完全正常没有缺陷的 ...

  6. weblogic/utils/NestedException

    Working with Weblogic 8.1, it’s fine just to put jar of weblogic-8.1.jar into your classpath, your c ...

  7. map 转换 xml ; xml转map

    public class MessageKit { public static String map2xml(Map<String, String> map) throws IOExcep ...

  8. Extjs 实现输入数量,实时更改总价

    // 总价 var totalNum = '0.00'; //总价初始值 var $total = new Ext.form.Label({ text: '消费金额 : ¥' + totalNum + ...

  9. linux系统命令解析(0基础篇)

    经常使用命令 ctrl+W+T    当进入gvim文档编辑界面后,假设是C文件,能够列出当前文件里的全部函数. Shift+*    当进入gvim文档编辑页面,能够搜索当前keyword. ech ...

  10. 【M25】将构造方法和非成员方法虚化

    1.所谓虚化,就是根据引用或者指针的真实类型,决定调用哪个方法. 2.构造方法虚化,就是根据引用(或者指针)的真实类型,构造出一个对象,如果指针的真实类型是Base,返回Base*:如果指针的真实类型 ...