`
modabobo
  • 浏览: 502422 次
文章分类
社区版块
存档分类
最新评论

Android中AsyncTask的使用

 
阅读更多
Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。在单线程模型中始终要记住两条法则:
1. 不要阻塞UI线程

2. 确保只在UI线程中访问Android UI工具包

当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,

如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。

但是,当我们涉及到比较耗时的操作,例如访问网络,读写数据库或文件等时,一般都是需要再开一个线程,

android提供了几种在其他线程中访问UI线程的方法。
Activity.runOnUiThread( Runnable )
View.post( Runnable )
View.postDelayed( Runnable, long )
Hanlder

这些类或方法同样会使你的代码很复杂很难理解,然而当你需要实现一些很复杂的操作并需要频繁地更新UI时这会变得更糟糕。

下面我们介绍一个在安卓中比较常用且轻量级的线程辅助类:AsyncTask。它使创建需要与用户界面交互的长时间运行的任务变得更简单。

AsyncTask是抽象类.AsyncTask定义了三种泛型类型 Params,Progress和Result。
  Params 启动任务执行的输入参数。
  Progress 后台任务执行的百分比。
  Result 后台执行任务最终返回的结果。

AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。
  1) 子类化AsyncTask
  2) 实现AsyncTask中定义的下面一个或几个方法
   onPreExecute(), 该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。
   doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
   onProgressUpdate(Progress...),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
   onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.

例子:我们保存数据到数据库中去,将保存部分的代码放到doInBackground(后台线程执行方法)中,保存的时候弹出

一个对话框,给用户相应的提示信息,保存完毕,将对话框关闭,部分代码如下:

ProgressDialog progressDialog = ProgressDialog.show(
				this,
				getString(R.string.tip),
				getString(R.string.saving));
		
		/**
		 * 第一个泛型:控制doInBackground的参数类型
		 * 第三个泛型:控制doInBackground的返回值类型和onPostExecute的参数类型
		 * doInBackground的返回值类型会传给onPostExecute当参数
		 */
		AsyncTask task = new AsyncTask<Void, Void, Integer>() {
			/**
			 * 在后台线程中调用doInBackground
			 */
			@Override
			protected Integer doInBackground(Void... params) {
				//保存到数据库
				ContentValues values = new ContentValues();
				values.put(Contact.NAME, nameText);
				values.put(Contact.PHONE, phoneText);
				values.put(Contact.PHOTO, selectedId);
				values.put(Contact.ADDRESS, addressText);
				long id = mgr.add(values);
				return (int)id;
			}

			/**
			 * 当doInBackground执行完毕后,回到主线程调用onPostExecute
			 */
			@Override
			protected void onPostExecute(Integer result) {
				//关闭对话框
				progressDialog.dismiss();
				if(result > 0){//保存成功
					//toast(R.string.save_success);
					//说明要刷新
					setResult(CODE_REFRESH);
					finish();
				}else{//保存失败
					toast(R.string.save_error);
				}
			}
		};
		
		//执行异步任务,execute参数会传给doInBackground方法
		task.execute(new Void[]{});


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics