Handler、Loop和MessageQueue
来源:互联网 发布:人丑还颜控 知乎 编辑:程序博客网 时间:2024/05/18 02:47
一、Android之线程信使
曾在网上看到一个段子。
面试时,面试官问码农:xxx是线程安全的吗?
码农果断答道:是线程安全的。
面试官:(⊙o⊙)…我正准备接着问为什么不是线程安全的
……
然后就没有然后了。
那么,同样的问题:Android的UI操作是线程安全的吗?
(不要回答的太果断啊)
答案肯定是:不是线程安全的。具体吗?我想这个链接已经说的基本清楚了:http://chenjinhua1595515.blog.163.com/blog/static/21583214720140834012400/
回归正题,Android中有一条规则:只允许UI线程修改Activity里的UI组件,而如果需要在新线程中更新UI线程的组件,则需要通过一个信使:Handler。
Handler类主要有两个作用:
(1)在新线程中发送消息。
(2)在UI线程中获取、处理消息。
好,so easy!完活儿。
二、Handler、Loop和MessageQueue组件
真的这么简单吗?新启动的线程何时发送消息?UI线程何时获取消息?以及消息的传递机制呢?这就有必要了解一下和Handler一起工作的小伙伴啦。
Message:消息(直译,哈哈)。Handler接收和处理的就是它。
Looper:(这个不太好直译)刚开始学的时候,一上来就是东西最难理解,后来发现这个东西就是连接MessageQueue和Handler的中间人,负责把MessageQueue中的Message取出来,送给Handler去处理。需要注意的是:每个线程只有一个Looper。
MessageQueue:消息队列。大家肯定都知道队列的实现机制,不知道也没事,一句话,先进先出。
在线程中使用Handler的步骤有以下三步:
(1)通过Looper的prepare()方法为当前线程创建Looper对象
private Looper() { mQueue = new MessageQueue(); mRun = true; mThread = Thread.currentThread();}可见,同时创建了与之配套的MessageQueue。
(2)创建Handler子类的实例,重写handleMessage()方法,该方法负责处理其他线程的消息。
Handler mHandler = new Hander() { @Override public void handleMessage(Message msg) { if(msg.what == VALUE) // WHAT YOU WANT TO DO }}(3)调用Looper的loop方法来启动Looper。loop方法是一个静态方法,网上有它的源代码,是一个死循环不断的取出MessageQueue中的消息,并将其分给该消息对应的Handler处理。代码较长,这里不再贴出。
三、网络编程时的多线程
在Android端的网络编程时(关于网络编程,后续博客中会具体阐述),多线程是必须的编程方法,比如:与服务器进行通信的代码需要在新线程中完成,响应用户操作的代码需要在UI线程中完成……(当然,根据需求,可能这里有非常多的线程,比如多线程下载),这里,仅举例说明网络连接的线程和主线程。
以最简单的登陆服务器为例:
loginButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {final String name = ((EditText) findViewById(R.id.log_in_name_input)).getText().toString();final String password = ((EditText) findViewById(R.id.log_in_password_input)).getText().toString();new Thread() {@Overridepublic void run() {try {HttpPost post = new HttpPost("http://xxx.xxx.xx.xxx:8080/APPLICATION_NAME/login.jsp");List<NameValuePair> params = new ArrayList<NameValuePair>();params.add(new BasicNameValuePair("name", name));params.add(new BasicNameValuePair("pass", password));post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));HttpResponse response = httpClient.execute(post);if (response.getStatusLine().getStatusCode() == 200) {String msg = EntityUtils.toString(response.getEntity());<strong>Looper.prepare();Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();Looper.loop();</strong>}}catch (Exception e) {e.printStackTrace();}}}.start();}});}在监听登陆按钮时,需要新启动一个线程,进行与服务器的连接,在监听到服务器成功返回响应之后,首先,通过response.getEntity()方法取得返回的内容,然后通过prepare()方法创建Looper对象,最后调用loop()方法启动Looper。
- Handler、Loop和MessageQueue
- Loop、Handler、MessageQueue和Message源码分析
- Handler、Loop、MessageQueue
- Handler类和Handler,Loop,MessageQueue的工作原理
- Handler类和Handler,Loop,MessageQueue的工作原理
- Handler,MessageQueue Loop 和Message的原理解析
- Android Handler (Loop MessageQueue) 解析
- android基础--Handler,Loop,MessageQueue
- Handler、Loop、MessageQueue的关系
- Handler, Loop, MessageQueue的工作原理
- Handler、Loop、MessageQueue的工作原理
- Handler、Loop、MessageQueue的工作原理
- Android Handler、Loop、MessageQueue的工作原理
- Handler,Loop,Message,MessageQueue,ThreadLocal关系详解
- Handler、Loop、MessageQueue的工作原理<温故知新>
- Android MessageQueue和Loop分析
- 第五课:Android中Handler、Loop、MessageQueue的工作原理和使用方法
- handler looper和messageQueue
- 关于一些设计模式(面试小问题,Java篇)
- 鹰蛋问题解析之动态规划
- 好久都没写博客了。
- Android 编程笔记 可返回键作用的ProgressDialog
- windows phone 8 开发学习笔记(二)
- Handler、Loop和MessageQueue
- IOS程序启动的过程
- 学习之路3----ResultSet可滚动和可更新的结果集
- Java 文件操作
- PL/SQL块分类
- 大话设计模式——外观模式(C++顾客抵押系统)
- login 登录页面(别小看这个页面在公司很有讲究的!昨天晚上熬夜写的)
- PAT1010. 一元多项式求导
- MySQL数据库最大连接数