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[]{});
分享到:
相关推荐
AsyncTask的用法
详解Android中AsyncTask的使用。
Android AsyncTask用法和异步加载图片通过AsyncTask 从网络上异步加载一张图片
Android_AsyncTask 关于AsyncTask 的一些常见应用。
Android AsyncTask的简单Demo,对应Blog文章:http://blog.csdn.net/dolacmeng/article/details/50215519
Android 使用AsyncTask异步更新UI界面
在Android中使用AsyncTask和Handler线程间交互的方式,详情参见博客:http://www.cnblogs.com/plokmju/p/android_AsyncTask.html和http://www.cnblogs.com/plokmju/p/android_Handler.html
android中AsyncTask和jni技术简单应用--附案例附代码
主要介绍了Android中异步类AsyncTask用法,分析总结了Async Task类的功能、特点及相关的使用技巧与注意事项,需要的朋友可以参考下
Android中AsyncTask实现多线程计数,UI主线程运行,启动另一个线程计数并在UI主线程上显示.
Android Handler AsyncTask 异步加载
Android开发之AsyncTask机制及使用细节例子源码 详见博客 http://www.cnblogs.com/samy/p/4217263.html
在Android中实现异步任务机制有两种方式,Handler和AsyncTask。 Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,...
Android中AsyncTask的用法实例[收集].pdf
这是Pro Android学习系列中AsyncTask部分的例子源代码。相关学习笔记见:http://blog.csdn.net/flowingflying/article/details/6212512
基于Android的AsyncTask异步任务, Android的AsyncTask将复杂的数据处理交由子线程, 将处理过程交由主线程处理
Android AsyncTask异步处理下载网页
Android_AsyncTask_详解
Android最全最简单的异步任务AsyncTask使用解析.一步到位彻底理解异步任务。
主要介绍了详解Android 中AsyncTask 的使用 的相关资料,这里提供实例帮助大家学习理解这部分内容,需要的朋友可以参考下