一、单线程模型

当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。

在开发Android 应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。

如果在非UI线程中直接操作UI线程,会抛出android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views,这与普通的java程序不同。

由于UI线程负责事件的监听和绘图,因此,必须保证UI线程能够随时响应用户的需求,UI线程里的操作应该向中断事件那样短小,费时的操作(如网络连接)需要另开线程,否则,如果UI线程超过5s没有响应用户请求,会弹出对话框提醒用户终止应用程序。

如果在新开的线程中需要对UI进行设定,就可能违反单线程模型,因此android采用一种复杂的Message Queue机制保证线程间通信。

Message Queue:

Message Queue是一个消息队列,用来存放通过Handler发布的消息。Android在第一次启动程序时会默认会为UI thread创建一个关联的消息队列,可以通过Looper.myQueue()得到当前线程的消息队列,用来管理程序的一些上层组件,activities,broadcast receivers 等等。你可以在自己的子线程中创建Handler与UI thread通讯。

通过Handler你可以发布或者处理一个消息或者是一个Runnable的实例。每个Handler都会与唯一的一个线程以及该线程的消息队列管理。

Looper扮演着一个Handler和消息队列之间通讯桥梁的角色。程序组件首先通过Handler把消息传递给Looper,Looper把消息放入队列。Looper也把消息队列里的消息广播给所有的Handler,Handler接受到消息后调用handleMessage进行处理。

(以上转自http://www.cnblogs.com/nio-nio/archive/2012/07/23/2604900.html)

二、多线程的实现

有以下几种方式:

1)Activity.runOnUiThread(Runnable)

2)View.post(Runnable) ;View.postDelay(Runnable , long)

3)Handler

4)AsyncTask

Android是单线程模型,这意味着Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行,所以你单纯的new一个Thread并且start()是不行的,因为这违背了Android的单线程模型。那么如何用好多线程呢?总结一下:  
事件处理的原则:所有可能耗时的操作都放到其他线程去处理。

对于第一种方法:

activity.runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
int i = 30;
textView.setText(""+i+" s");
}
}
});

第2,3种方法网络上资料较多,不再赘述。第4种方法在上一篇博文中已经介绍。

三、总结:

1)android系统是单线程系统,为了实现多线程的效果,采用了message queue。

2)为实现多线程,可采用runOnUiThread,post,handle,AsyncTask技术实现。

android开发之多线程实现方法概述的更多相关文章

  1. 关于无法下载android开发工具的解决方法

    目前中国内地访问android网站需要FQ.不过这个网站http://www.androiddevtools.cn/提供了所有的和官网上一样的android开发工具和一些其他问题的解决方法.为andr ...

  2. Android开发专业名词及工具概述

    前言: 系统的学习下Android开发中涉及到的一些专业名词 和Android开发工具 名词: 一.SDK(Software Development Kit) 软件开发工具包:一般都是一些软件工程师为 ...

  3. Android开发中常用到方法总结

    1.判断服务是否在运行中 public static boolean isServiceRunning(Context context, String serviceName) {  boolean ...

  4. Android开发之多线程下载、断点续传、进度条和文本显示

    代码实现了在Android环境下的多线程下载.断点续传.进度条显示和文本显示百分数: import java.io.BufferedReader; import java.io.File; impor ...

  5. Android开发BUG及解决方法2

    错误描述: 错误分析: 程序依赖的两个包冲突 解决方法: 在build.gradle文件中android节点下加packagingOptions节点

  6. Android开发BUG及解决方法1

    错误描述: 问题1: Error:Execution failed for task ':app:transformClassesWithDexForDebug'. > com.Android. ...

  7. Android开发BUG及解决方法

    错误描述 问题1: 按照提示打开gradle-wrapper.properties文件 并且将gradle-2.8-all.zip改为gradle-2.10-all.zip,重新导入项目 问题2: 却 ...

  8. Android开发日常-listview滚动方法梳理

    listview滚动方法梳理 1.setSelection(position); 滚动到指定条目 2.setSelectionFromTop(position,y): 距离指定条目向下偏移y(像素) ...

  9. Android开发常见问题及解决方法

    http://blog.csdn.net/silangquan/article/details/8104414

随机推荐

  1. [译]如何定义python源文件的文件编码

    简介 这篇文章是为了介绍定义python源文件文件编码的方法.python解释器可以根据所指定的编码信息对当前文件进行解析.通常来说,这种方法可以提高解析器对Unicode编码的源文件的识别,并且支持 ...

  2. input中的disabled 和 readonly的区别

    1.Readonly只针对input(text / password)和textarea有效, 而disabled对于所有的表单元素都有效, 2.但是表单元素在使用了disabled后,当我们将表单以 ...

  3. C/C++中的联合体

    C/C++中的联合体 利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间.当访问其内成员时可用"."和"->"来直接访问. 当多个 ...

  4. Thinkpad W540通过扩展坞连接显示器后蓝屏原因

    问题:Thinkpad W540通过扩展坞连接显示器后蓝屏 描述:直接扩展连接显示器重启电脑,一直黑屏,等待光标,进不了桌面.分离扩展,进入后,再连接显示器,蓝屏死机. 解决:用尽办法,重装显示驱动, ...

  5. css3 3D变形 入门(一)

    css3 3D.html div.oembedall-githubrepos { border: 1px solid #DDD; list-style-type: none; margin: 0 0 ...

  6. Git合并分支命令:git merge --ff

    今天研究了一下git merge命令常用参数,并分别用简单的例子实验了一下,整理如下: 输入git merge -h可以查看相关参数: --ff  快速合并,这个是默认的参数.如果合并过程出现冲突,G ...

  7. 游戏UI框架设计(一) : 架构设计理论篇

    游戏UI框架设计(一) ---架构设计理论篇 前几天(2017年2月)看到一篇文章,国内王健林.马云等大咖们看好的未来十大最有"钱途"产业中,排名第一的就是"泛娱乐&qu ...

  8. js加载XML文件

    // XML文件 <?xml version="1.0" encoding="gb2312"?> <root> <father n ...

  9. Java 练习(多态,instanceof)

    题目:*(封装.继承)设计如下的继承树: Accout 表示银行账户,id 属性表示账户id,balance 表示账户余额,password 表示账户密码: SavingAccount 表示储蓄账户, ...

  10. Laravel / Lumen 框架修改 创建时间 和 更新时间 对应字段

    为避免浪费时间--先上解决方案 在Model中重写 CREATED_AT 和 UPDATED_AT 两个类常量就可以了,这两个常量分别是创建时间和更新时间的字段名. ================= ...