专栏首页老欧说安卓Android开发笔记(四十九)异步任务处理AsyncTask

Android开发笔记(四十九)异步任务处理AsyncTask

AsyncTask异步任务

Thread+Handler方式虽然能够实现多线程的通信处理,但是写起代码来颇为繁琐,所以Android提供了AsyncTask这样一个轻量级的异步任务类,其内部封装好Thread+Handler,方便了码农的工作,类似已封装好的多线程处理类还有IntentService(具体见《Android开发笔记(四十一)Service的生命周期》)。AsyncTask适用于HTTP通信,包括下载、http调用等等。 AsyncTask是个模板类(AsyncTask<Params, Progress, Result>),继承它的新类需要指定模板的参数类型,模板参数说明如下: Params : 任务启动时的输入参数,比如http访问的url、请求参数等等。可设置为String类型或者自定义的数据结构 Progress : 任务执行的进度。可设置为Integer类型 Result : 任务执行完的结果。可设置为String类型或者自定义的数据结构 下面是要重写的方法,不能直接调用: doInBackground : 异步处理操作都放在该方法中,params参数对应execute方法的输入参数。该方法运行于分线程,所以不能操作UI,其他方法都能操作UI onPreExecute : 在doInBackground执行之前调用 onProgressUpdate : doInBackground方法中调用publishProgress时会触发该方法,通常用于处理过程中刷新进度条 onPostExecute : 在doInBackground执行完毕时调用,通常用于处理完毕后刷新展示页面 onCancelled : doInBackground方法中调用cancel时会触发该方法 下面是可直接调用的方法: execute : 开始执行异步处理任务。 executeOnExecutor : 以指定线程池模式开始执行任务。THREAD_POOL_EXECUTOR表示异步线程池,SERIAL_EXECUTOR表示同步线程池。默认是SERIAL_EXECUTOR。 publishProgress : 更新进度。该方法只能在doInBackground方法中调用,调用后会触发onProgressUpdate方法。 cancel : 取消任务。该方法调用后,doInBackground的处理立即停止,并且接着调用onCancelled方法,而不会调用onPostExecute方法。 get : 获取处理结果。 getStatus : 获取任务状态。PENDING表示还未执行,RUNNING表示正在执行,FINISHED表示执行完毕 isCancelled : 判断该任务是否取消。true表示取消,false表示未取消

ProgressBar进度条

ProgressBar是嵌入在页面内的进度条,主要用于展示页面加载或者文件下载的进度。 ProgressBar的常用样式 progressBarStyle : 中型圆圈进度 progressBarStyleSmall : 小型圆圈进度 progressBarStyleLarge : 大型圆圈进度 progressBarStyleHorizontal : 水平进度条。注意,只有水平进度条才能设置当前进度,圆圈进度无法设置当前进度 样式设置方式为,在xml布局文件的ProgressBar增加如下的style属性:

        style="?android:attr/progressBarStyleHorizontal"

ProgressBar的常用方法 注意只有样式设置为progressBarStyleHorizontal时,进度设置才会生效。 setProgress : 设置当前进度 getProgress : 获取当前进度 setSecondaryProgress : 设置当前第二进度。如在线观看视频,第一进度是观看进度,第二进度是下载进度 getSecondaryProgress : 获取当前第二进度 setMax : 设置进度条的进度上限 getMax : 获取进度条的进度上限 incrementProgressBy : 设置当前进度的增量 incrementSecondaryProgressBy : 设置当前第二进度的增量

ProgressDialog进度对话框

ProgressDialog是浮在页面上方的进度对话框,作用与ProgressBar类似。ProgressDialog继承自AlertDialog,内部又集成了ProgressBar,所以拥有AlertDialog的所有方法,以及ProgressBar的公有方法。下面是ProgressDialog的常用方法(与ProgressBar同名的方法见上面,就不重复列了): show : 显示对话框。需要在各属性设置完成后再调用show方法。 isShowing : 判断对话框是否显示 dismiss : 关闭对话框。以上三个方法继承自Dialog类 setTitle : 设置对话框标题 setMessage : 设置对话框消息内容 setIcon : 设置对话框图标。以上三个方法继承自AlertDialog类 setProgressStyle : 设置进度条样式。默认取值STYLE_SPINNER表示圆圈进度,取值STYLE_HORIZONTAL表示长条进度。 静态show : 简化ProgressDialog的操作代码,一句代码就搞定进度对话框的设置与显示。可指定标题和消息内容,进度条样式为默认的圆圈进度。

public static ProgressDialog show(Context context, CharSequence title, CharSequence message)

使用示例

下面是异步任务处理显示进度条的效果图:

下面是异步处理任务的示例代码:

import android.os.AsyncTask;

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

	private final static String TAG = "ProgressBarTask";
	private ProgressListener mListener;

	public ProgressAsyncTask() {
		super();
	}
	
	public void setProgressListener(ProgressListener listener) {
		mListener = listener;
	}
	
	public ProgressListener getProgressListener() {
		return mListener;
	}
	
	@Override
	protected String doInBackground(String... params) {
		int ratio = 0;
		for (; ratio<=100; ratio+=5) {
			//睡眠200毫秒模拟网络通信处理
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			publishProgress(ratio);
//			if (ratio >= 50) {
//				cancel(false);
//			}
		}
		return params[0];
	}

	@Override
	protected void onPreExecute() {
		mListener.onBegin();
	}

	@Override
	protected void onProgressUpdate(Integer... values) {
		mListener.onUpdate(values[0], 0);
	}

	@Override
	protected void onPostExecute(String result) {
		mListener.onFinish(result);
	}

	@Override
	protected void onCancelled(String result) {
		mListener.onCancel(result);
	}
	
}

下面是异步处理任务的调用代码:

import com.example.exmthread.task.ProgressAsyncTask;
import com.example.exmthread.task.ProgressListener;

import android.app.Activity;
import android.app.ProgressDialog;
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 AsyncTaskActivity extends Activity implements OnClickListener, ProgressListener {

	private TextView tv_async;
	private ProgressBar pb_async;
	private ProgressDialog m_pd;
	
	public int mShowMode;
	public int BAR_CIRCLE = 0;
	public int BAR_HORIZONTAL = 1;
	public int DIALOG_CIRCLE = 10;
	public int DIALOG_HORIZONTAL = 11;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_async);

		Button btn_bar = (Button) findViewById(R.id.btn_bar);
		Button btn_dialog_circle = (Button) findViewById(R.id.btn_dialog_circle);
		Button btn_dialog_hrz = (Button) findViewById(R.id.btn_dialog_hrz);
		btn_bar.setOnClickListener(this);
		btn_dialog_circle.setOnClickListener(this);
		btn_dialog_hrz.setOnClickListener(this);
		
		tv_async = (TextView) findViewById(R.id.tv_async);
		pb_async = (ProgressBar) findViewById(R.id.pb_async);
	}

	@Override
	public void onClick(View v) {
		if (v.getId() == R.id.btn_bar) {
			startTask(BAR_HORIZONTAL, "三国演义");
		} else if (v.getId() == R.id.btn_dialog_circle) {
			startTask(DIALOG_CIRCLE, "西游记");
		} else if (v.getId() == R.id.btn_dialog_hrz) {
			startTask(DIALOG_HORIZONTAL, "红楼梦");
		}
	}
	
	private void startTask(int mode, String msg) {
		mShowMode = mode;
		ProgressAsyncTask asyncTask = new ProgressAsyncTask();
		asyncTask.setProgressListener(this);
		asyncTask.execute(msg);
	}
	
	private void closeDialog() {
		if (m_pd != null && m_pd.isShowing() == true) {
			m_pd.dismiss();
		}
	}

	@Override
	public void onFinish(String result) {
		String desc = String.format("您要阅读的《%s》已经加载完毕", result);
		tv_async.setText(desc);
		closeDialog();
	}

	@Override
	public void onCancel(String result) {
		String desc = String.format("您要阅读的《%s》已经取消加载", result);
		tv_async.setText(desc);
		closeDialog();
	}

	@Override
	public void onUpdate(int progress, int sub_progress) {
		tv_async.setText("当前加载进度为" + progress + "%");
		if (mShowMode == BAR_HORIZONTAL) {
			pb_async.setProgress(progress);
			pb_async.setSecondaryProgress(sub_progress);
		} else if (mShowMode == DIALOG_HORIZONTAL) {
			m_pd.setProgress(progress);
			m_pd.setSecondaryProgress(sub_progress);
		}
	}

	@Override
	public void onBegin() {
		tv_async.setText("开始加载");
		if (m_pd == null || m_pd.isShowing() != true) {
			if (mShowMode == DIALOG_CIRCLE) {
				m_pd = ProgressDialog.show(this, "稍等", "页面加载中……");
			} else if (mShowMode == DIALOG_HORIZONTAL) {
				m_pd = new ProgressDialog(this);
				m_pd.setTitle("稍等");
				m_pd.setMessage("页面加载中……");
				m_pd.setIcon(R.drawable.ic_search);
				m_pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
				m_pd.show();
			}
		}
	}

}

点此查看Android开发笔记的完整目录

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android开发笔记(序)写在前面的目录

    一方面写写自己走过的弯路掉进去的坑,避免以后再犯;另一方面希望通过分享自己的经验教训,与网友互相切磋,从而去芜存菁进一步提升自己的水平。因此博主就想,入门的东西...

    用户4464237
  • Android开发笔记(九十一)工厂模式

    工厂模式是一种常用的实例化对象设计模式。 程序开发很多时候都在不停地敲if、else,因为业务需求总在发展变化,今天客户要求生产A产品,明天客户要求把...

    用户4464237
  • Android开发笔记(八十六)几个特殊的类

    interface是一些功能的集合,但它只定义了对象必须实现的成员,而不包含成员的实现代码,成员的具体代码由实现接口的类提供。Android对接口的使用场景...

    用户4464237
  • 寒冬也挡不住进大厂的决心,Android面试完整知识架构,面试需要掌握的都在这里!

    年年寒冬,年年也挡不住一个Android程序员追求大厂的决心。想要进入大厂,我们需要掌握哪些知识点呢?这里,我为大家梳理了一个整体的知识架构。整体包括Java、...

    Android技术干货分享
  • Android 多线程:AsyncTask的原理 及其源码分析

    在进行源码分析前,先介绍`AsyncTask`中的类 & 核心方法

    Carson.Ho
  • Android开发笔记(五十八)铃声与震动

    SeekBar继承自进度条ProcessBar,有关ProcessBar的介绍见《Android开发笔记(四十九)异步任务处理AsyncTask》。Seek...

    用户4464237
  • Android 多线程-----AsyncTask详解

    本篇随笔将讲解一下Android的多线程的知识,以及如何通过AsyncTask机制来实现线程之间的通信。

    杨奉武
  • Android开发笔记(一百零六)支付缴费SDK

    第三方支付指的是第三方平台与各银行签约,在买方与卖方之间实现中介担保,从而增强了支付交易的安全性。国内常用的支付平台主要是支付宝和微信支付,其中支付宝的市场...

    用户4464237
  • Art of Android Development Reading Notes 11

    《Android开发艺术探索》读书笔记 (11) 第11章 Android的线程和线程池

    宅男潇涧

扫码关注云+社区

领取腾讯云代金券