专栏首页老欧说安卓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开发笔记(四)字符串格式化

    博主原来是搞C的,C里面有sprintf来格式化字符串,后来转到java变傻了,拼接String只会用n个“+”,要么就是用StringBuilder的ap...

    用户4464237
  • Android开发笔记(六十二)HTTP数据格式的解析

    android有两种主流的json解析方案,一种是sdk自带的由Google提供的json(包名前缀为org.json),另一种是Alibaba提供的第三方...

    用户4464237
  • Android开发笔记(八十四)使用Properties读写属性值

    Java中的配置文件常为.properties文件,而Properties类便是读写此类文件的工具。属性文件有两种格式,一种是文本格式,其内容是“键=值”的...

    用户4464237
  • 前端-小公司的前端可以怎么做?

    之前经常有人发文说到底要去小公司还是大公司,思考几年的经历,其实大公司小公司不重要,好的团队才重要!

    grain先森
  • Java字符串面试问答

    字符串是使用最广泛的Java的类之一。在这里,我列出了一些重要的Java的字符串面试问答。

    淡定的蜗牛
  • 分布式作业 Elastic-Job-Lite 源码分析 —— 注册中心

    ZookeeperRegistryCenter,基于 Zookeeper 注册中心。从上面的类图可以看到,ZookeeperRegistryCenter 实现 ...

    芋道源码
  • Java 动手写爬虫: 四、日志埋点输出 & 动态配置支持

    第四篇, 日志埋点输出 & 动态配置支持 前面基本上实现了一个非常简陋的爬虫框架模型,很多关键链路都没有日志,在分析问题时,就比较麻烦了,因此就有了这一篇博文...

    小灰灰
  • 【侠客行】Lombok深度解析

    Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率。例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/sett...

    大蕉
  • Java高效分割字符串

    最近优化一段代码的调用时间,发现性能瓶颈居然是io和split!io操作慢情有可原,那么对于split有没有更高效的方法呢?

    weishu
  • Java虚拟机堆和栈详细解析,以后面试再也不怕问jvm了!

    Java堆是和Java应用程序关系最密切的内存空间,几乎所有的对象都放在其中,并且Java堆完全是自动化管理,通过垃圾收集机制,垃圾对象会自动清理,不需自己去释...

    程序员追风

扫码关注云+社区

领取腾讯云代金券