我们知道,Android系统为了提高程序的实时响应能力,不允许在UI线程中进行耗时的操作,否则会出现ANR异常,因此必须将耗时的任务放到非UI线程中执行。Android/Java提供了很多类来帮助大家完成异步操作,比如:Thread类,Timer类,AsyncTask类,HandlerThread类,以及Executor接口。这些类都分别在什么场合下使用呢?


本文简单地总结一下Android开发中常见的多线程类型和解决方案,并比较和分析了各个方案的区别,以便更好地理解和应用这些API接口。


1. 单项异步任务


[场景]:下载一个APK文件,拷贝一个大文件。


[方案]:Thread类,AsyncTask类


[比较]:


AsyncTask提供了onProgressUpdate和onPostExecute通知调用者任务执行的进度和结果,在函数内可以直接执行UI操作。


而Thread中不能直接操作UI界面,而要通过Activity.runOnUiThread或者借助Handler来完成UI的更新。


所以Thread更适合执行一些不需要跟UI频繁交互的单项任务,而AsyncTask相反。



2. 定时/循环执行的任务


[场景]:定时刷新UI(如:秒表),保持TCP心跳连接。


[方案]:“Thread + sleep”,定时器Timer


[比较]:


“Thread + sleep” 方案示例:


new Thread(new Runnable() {    @Override    public void run() {while(!EXIT) {    Thread.sleep(1000);            mListener.onTimeArrived();}    }}).start();


两者都不能在循环中执行UI更新操作,而必须借助Activity.runOnUiThread或者Handler来完成UI的更新。


由于Thread方案中onTimeArrived()占用了部分时间,所以这种方案的定时并不准确,而Timer是由系统创建异步通知的定时器,会更加准确,所以推荐使用Timer来完成定时任务。


3. 工作线程


工作线程启动后处于一种等待“命令”/“消息”的休眠状态,当接收到“命令”/“消息”后,将它放入“命令”/“消息”队列,然后唤醒线程依次串行或者并行执行。


[场景]:“生产者--消费者”模式,TCP Server端命令处理程序


[方案]: “Thread + condition/lock” ,HandlerThread类,线程池Executor


[比较]:


HandlerThread类是Android系统提供了封装好了Loop循环的Thread类,可以更加便捷地完成CallerThread和WorkThread的命令/消息交互。当然,我们也可以用Thread和Condition/Lock方式实现同样的效果,只不过要自己实现更多的代码。


前面的两种方式,都是“串行”的方式在执行“命令”,如果希望提供并发性,同时开启和管理多个线程来执行任务,则可以考虑使用Executor


以上就是我对Android多线程编程的简单小结,文中有任何不清楚或者不正确的地方,欢迎留言或者来信lujun.hust@gmail.com交流讨论,或者关注我的新浪微博 @卢_俊 获取最新的文章和资讯。


更多相关文章

  1. Android多线程下载远程图片
  2. 后台应用不应做Android待机电池杀手
  3. Android(安卓)创建定时任务
  4. android,内存优化详解
  5. Android(安卓)内存优化
  6. Android消息循环机制源码深入理解
  7. Android(安卓)异步消息处理机制(Handler 、 Looper 、MessageQueu
  8. Android消息机制之ThreadLocal浅析
  9. Android多线程下载远程图片

随机推荐

  1. php第一天的作业
  2. 演绎PHP 和 JavaScript 遍历数组
  3. php 之循环
  4. PHP0802第一次作业提交
  5. php遍历数组与js遍历数组的区别
  6. 0802作业
  7. 0802-演绎php遍历数组与js遍历数组的区别
  8. 简单的选显卡和懒加载
  9. php第一天---变量
  10. 0803作业