Android异步任务框架AsyncTask由潜入深
来源:互联网 发布:linux nanosleep使用 编辑:程序博客网 时间:2024/05/17 02:36
一、引子
android中新手比较容易犯的一种错误就是界面响应消息阻塞超时。亦即当界面消息在5秒钟内没有完成响应,android系统将自动判断对应activity已无响应,从而系统报错。
下面来看一个简单的例子
该按键的响应逻辑为使UI线程休眠10秒,那么当我按了一下按键后再按一下按键,第二次按键在5秒后还没有被响应,所以应用程序报错了。
代码如下:
例1:
public class TimeOutActivity extends Activity {Button mButton;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.time_out_activity);mButton = (Button) findViewById(R.id.btn_timeout);mButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {try {TimeUnit.SECONDS.sleep(10);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}});}}
所以往往我们在编写UI后台的响应逻辑时,往往需要启动一个后台的线程来进行复杂好使的处理。
通常我们会使用Thread和header来帮组我们解决该问题。
如下例
例2:
public class UIHandlerActivity extends Activity {private static final int OPER_RESAULT = 0x01;private Button btn_start;private static int time = 0;private TextView tv_resault;private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch(msg.what) {case OPER_RESAULT:String resault = (String) msg.obj;tv_resault.setText(resault);break;}}};private Runnable operation = new Runnable() {@Overridepublic void run() {for(int i = 1 ; i <= 1000 ; i++) for(int j=1 ; j <= 10000 ; j++);mHandler.sendMessage(mHandler.obtainMessage(OPER_RESAULT, "第" + (++time) + "次运算"));}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.ui_handler_activity);btn_start = (Button) findViewById(R.id.btn_timeout);tv_resault = (TextView) findViewById(R.id.tv_resault);btn_start.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Thread mThread = new Thread(operation);mThread.start();}});}}
二、初窥Async Task
由于后台线程的管理以及对应handler逻辑的维护往往也会比较繁琐,所以android提供了一个异步工具类AsyncTask。它使得UI thread的使用变得异常简单。它使创建需要与用户界面交互的长时间运行的任务变得更简单,不需要借助线程和Handler即可实现。
根据google关于AsyncTask的参考文档可知,一个AsyncTask的工作流程图如下
所以我们在使用AsyncTask时不用关系UI线程阻塞的问题。
我们使用AsycnTask只需要
1)实现doInBackground()接口并将我们需要的计算放在我们实现的doInBackground()方法中。
2)继承onPostExecute()方法并将根据计算结果对应UI的操作放在实现的onPostExecute()方法中。
下面我使用AsyncTask实现上面的例子:
例3:
public class AsyncTaskDemoActivity extends Activity {private Button btn_start;private TextView tv_resault;private static int time = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.ui_handler_activity); btn_start = (Button) findViewById(R.id.btn_timeout);tv_resault = (TextView) findViewById(R.id.tv_resault);btn_start.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {new Operation().execute();}}); } class Operation extends AsyncTask {@Overrideprotected Object doInBackground(Object... params) {for(int i = 1 ; i <= 1000 ; i++) for(int j=1 ; j <= 10000 ; j++);return null;}@Overrideprotected void onPostExecute(Object result) {tv_resault.setText( "第" + (++time) + "次运算");} }}
但是我们使用的时候应该注意以下几个问题:
1) Task的实例 必须在UI thread中创建
2) execute方 法必须在UI thread中调用
3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法
4) 该task只能被执行一次,否则多次调用时将会出现异常
注意这几点后,使用AsyncTask将会变得非常简便。
本文中所有代码均能在以下地址下载:
例1-3下载
- Android异步任务框架AsyncTask由潜入深
- Android异步任务AsyncTask
- Android--AsyncTask异步任务
- Android AsyncTask异步任务
- Android 异步任务 AsyncTask
- android 异步任务 AsyncTask
- Android AsyncTask 异步任务
- Android AsyncTask异步任务
- 【Android】异步任务AsyncTask
- Android AsyncTask异步任务
- android AsyncTask异步任务
- Android异步任务AsyncTask
- Android:AsyncTask -- 异步任务
- Android 异步任务:AsyncTask
- Android异步任务AsyncTask
- Android异步任务AsyncTask
- Android异步任务AsyncTask
- Android AsyncTask异步任务
- 跟着开发手册学习php
- 李长春抵达伊斯兰堡开始访问巴基斯坦-李长春-巴基斯坦-伊斯兰堡
- fatal: Couldn't obtain random bytes (error 604389476)
- 安全算法:3DES密钥长度
- Linux启动时间的极限优化
- Android异步任务框架AsyncTask由潜入深
- 无法直接打开excel文件
- VS2010 在Win 7 附加w3wp.exe进程进行调试和权限问题
- :获取ImageView中的图像需要注意的问题
- DirectX简介 第五篇 DirectInput简介
- webservices 使用 Session 、 Application
- Ubuntu 12.04 在root登陆之后没有声音的解决方法
- 九月初四
- MFC CTreectrl DeleteAllItems 删除ITEM后从新加载数据