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
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值