Android AsyncTask详解

在Google中Android API对AsyncTask解析:

AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

AsyncTask的使得适当的和易于使用的用户界面线程。这个类允许执行后台操作而无需操作线程和/或处理程序发布在UI线程上的结果。

AsyncTask is designed to be a helper class aroundThread andHandler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by thejava.util.concurrent pacakge such asExecutorThreadPoolExecutor andFutureTask.

AsyncTask的设计是围绕Thread和Handler一个辅助类,并不构成一个通用线程框架。AsyncTasks最好应采用短作业(几秒钟之最。)如果你需要保持运行很长一段时间的线程,我们强烈建议您使用,如提供的java.util.concurrent中pacakge的各种API遗嘱执行人,的ThreadPoolExecutor和FutureTask。

An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress andResult, and 4 steps, calledonPreExecute,doInBackgroundonProgressUpdate andonPostExecute.

异步任务是由一个后台线程,其结果公布在UI线程上运行的计算确定。一个异步任务由3泛型类型,称为Params,进展和成效,以及4个步骤,称为onPreExecute,doInBackground,onProgressUpdate和onPostExecute定义。

在Android实现异步机制有两种方式:分别是AsyncTask与Handler

AsyncTask实现原理

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

优点:

1、简单、快捷

2、过程可控

缺点:

1、在使用多个异步操作和并需要UI变更时,该操作就变得复杂

Handler实现原理

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

优点:

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

2、对于多个后台任务是,简单、清晰

缺点:

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

总结:

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

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

 

AsyncTask详解:

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

AsyncTask是直接继承Object,其位于android.os.AsyncTask,要使得AsyncTask工作,我们必须三个泛型参数,并重载几个方法(至少一个)

AsyncTask定义了三个泛型参数:Params,Progress与Result

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

经常重载的两个方法:

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

有必要的话,你还可以重写以下的三个方法,但不是必须的:

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

一个异步任务的执行一般包括以下几个步骤:

  • execute(Params... params)执行一个异步任务,我们需要在代码中调用此方法,触发异步任务的执行;调用UI线程上执行任务之前。这个步骤是通过示出在用户界面的进度条通常用于设置任务
  • onPreExecute()在执行execute(Params... params)后立即执行,一般用来在执行后台任务前对UI做的一些标记;启动一个进度对话框,向用户显示任务进度情况。
  • doInBackground(Params…)在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果,在执行过程中可以调用publicProgress(Progress…)来更新任务的进度
  • onProgressUpdate(Progress…) 在调用publicProgress(Progress…)时,此方法被执行,直接将进度信息更新在UI组件上
  • onPostExecute(Result) 在后台操作结束后,此方法将被调用,计算结果将作为参数传递到此方法中,直接将结果显示在UI组件上

调用AsyncTask必须必须遵守的规则:

  • AsyncTask实例必须在UI 线程中创建
  • exeucte()方法必须在UI线程中调用
  • 不要手动的调用doInBackground(Params…)onPostExecute(Result) onProgressUpdate(Progress…) 、onPreExecute()这几个方法。
  • 该AsyncTask实例只能别调用一次,否则多次调用时将会出现异常
  • 不能在doInBackground(Params…)方法中更改UI组件的信息


实现一个简单的例子,可以明确进度并且可以取消异步操作的

布局:

<?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" 
    />
    <Button
    android:id="@+id/button03"
  	android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="更新progressbar"
    />
</LinearLayout>


AsyncTask的继承类


package com.sym.asynctaskdemo;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.AsyncTask;
import android.widget.TextView;

public class ProgressBarAsyncTask extends AsyncTask<Integer, Integer, String>{

	private TextView textView;
	private ProgressDialog progressBar;
	private Context context;
	public static boolean isrunning = false;
	
	public ProgressBarAsyncTask(TextView textView, Context context) {
		super();
		this.textView = textView;
		this.context = context;
	}


	/**
	 * 这里的Integer参数对应AsyncTask中的第一个参数 
	 * 这里的String返回值对应AsyncTask的第三个参数
	 * 该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改
	 * 但是可以调用publishProgress方法触发onProgressUpdate对UI进行操作
	 */
	@Override
	protected String doInBackground(Integer... params) {
		int i = 0;
		if(this.isCancelled()){
			return null;
		}else{
			for (i = 2; i <= 100; i+=2) {
				try {
					publishProgress(i);//这个必须执行,否则不会更新
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					return null;//这里必须返回空,否则无法停止后台的操作
				}
			}
			
			return params[0].intValue() + "";
		}
		

	}


	/**
	 * 这里的String参数对应AsyncTask中的第三个参数(也就是接收doInBackground的返回值)
	 * 在doInBackground方法执行结束之后在运行,并且运行在UI线程当中 可以对UI空间进行设置
	 */
	@Override
	protected void onPostExecute(String result) {
		// TODO Auto-generated method stub   
		super.onPostExecute(result);
		textView.setText("异步操作执行结束" + result);
		progressBar.setTitle("异步操作执行结束");
		progressBar.cancel();
		isrunning = true;
	}

	//该方法运行在UI线程当中,并且运行在UI线程当中 可以对UI空间进行设置
	@SuppressWarnings("deprecation")
	@Override
	protected void onPreExecute() {
		// TODO Auto-generated method stub
		super.onPreExecute();
		
		textView.setText("开始执行异步线程");
		progressBar = new ProgressDialog(context);
		progressBar.setTitle("开始执行异步线程");
		progressBar.setMessage("in progress......");
		
		progressBar.setButton("取消", new android.content.DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				if(!isrunning){//判断标识
					ProgressBarAsyncTask.this.cancel(true);
				}
				
			}
		});
		progressBar.setCancelable(true);
		progressBar.setOnCancelListener(new OnCancelListener() {
			
			@Override
			public void onCancel(DialogInterface dialog) {   
				// TODO Auto-generated method stub
				if(!isrunning){//判断标识
					ProgressBarAsyncTask.this.cancel(true);
				}
			}
		});
		progressBar.setIndeterminate(false);//设置Indeterminate为false,可以明确进度
		progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		progressBar.setMax(100);
		progressBar.setCanceledOnTouchOutside(false);
		progressBar.show();
	}

	/**
	 * 这里的Intege参数对应AsyncTask中的第二个参数
	 * 在doInBackground方法当中,,每次调用publishProgress方法都会触发onProgressUpdate执行
	 * onProgressUpdate是在UI线程中执行,所有可以对UI空间进行操作
	 */
	@Override
	protected void onProgressUpdate(Integer... values) {
		// TODO Auto-generated method stub
		super.onProgressUpdate(values);
		if(this.isCancelled()) return;//判断AsyncTask是否取消,如果是,则停止更新;否则继续
		int vlaue = values[0];
		progressBar.setProgress(vlaue);
	}


	
	@Override
	protected void onCancelled() {
		// TODO Auto-generated method stub
		super.onCancelled();
		isrunning = true;
		progressBar.setTitle("异步操作暂停");
		textView.setText("异步操作暂停");
		progressBar.setProgress(0);
	}
	
}
 
 
 
 

Activity主类:

package com.sym.asynctaskdemo;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

	private Button button;
	private TextView textView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button = (Button)findViewById(R.id.button03);
		
        textView = (TextView)findViewById(R.id.textView01);
        
        button.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				ProgressBarAsyncTask asyncTask = new ProgressBarAsyncTask(textView, MainActivity.this);
				asyncTask.execute(2000);
				ProgressBarAsyncTask.isrunning = false;//修改标识
			}
		});

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}





运行结果图:


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值