Android 多线程编程:Handler消息传递机制—刷新UI主界面
2015-09-09 12:06
483 查看
一、为什么使用Handler
当一个Activity运行的时候,会开启一条主线程,主线程主要负责处理与UI相关的事件,主线程不允许其他子线程操控它,更新UI界面。既然不允许我们在子线程中操控UI界面,那么,像我们平时所见的点击获取验证码,不断更新UI界面的操作又怎样实现的呢?这里就用到了我们的Handler消息传递的机制。二、Handler消息传递机制介绍
Handler类的主要作用有两个:1、在新启动的线程中发消息。
2、在主线程中获取、处理消息。
也就是线程发消息给主线程,在handler中存在一个MessageQueue(消息队列),线程的消息发给了MessageQueue,我们再通过Handler类中的handleMessage方法重写进行相关操作。Handler会不断的从MessageQueue中获取并处理消息。当然除了能从线程向主线程发消息,我们也可以从主线程向线程发消息,只是这种情况不常见,一般不会这样做。
补充
Handler 机制原理三、使用实例
子线程向主线程发消息
1、开启一个新的线程,在新的线程中new一个Message,设置Message,并由发送Message2、主线程中接收Handler,并进行UI的更新操作
[code]package com.example.newjc; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity implements OnClickListener{ private Button mbtn_second; private Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what) { case TIME_DESC: String s=(String) msg.obj; mbtn_second.setText(s); break; default: break; } } }; public static final int TIME_DESC=0x22; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mbtn_second=(Button) findViewById(R.id.bt_second); mbtn_second.setOnClickListener(this); } @Override public void onClick(View v) { new Thread (new Runnable() { @Override public void run() { int count=60; while(count>0){ count--; try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Message msg=new Message(); msg.obj=count+"秒"; msg.what=TIME_DESC; handler.sendMessage(msg); } } }).start(); } }
为了简化操作,我们对以上代码进行修改,采用递归思想来实现同样效果
注意:这里的代码并没有用到子线程,纯粹是handler的一种使用方式。
[code]@Override public void onClick(View v) { count=60; //发送一个空消息 handler.sendEmptyMessage(TIME_DESC); }
[code]private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case TIME_DESC: count--; mbtn_second.setText(count + "秒"); if (count > 0) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } handler.sendEmptyMessage(TIME_DESC); } break; default: break; } } };
主线程给子线程发消息
[code]public class MainActivity extends Activity implements OnClickListener { private Button mbtn_second; private Button mbtn_second2; private int count; private Mythread thread; public static final int TIME_DESC = 0x22; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mbtn_second = (Button) findViewById(R.id.bt_second); mbtn_second2 = (Button) findViewById(R.id.bt_second2); mbtn_second.setOnClickListener(this); mbtn_second2.setOnClickListener(this); } @Override public void onClick(View v) { //count = 60; //handler.sendEmptyMessage(TIME_DESC); switch (v.getId()) { case R.id.bt_second: thread=new Mythread(); thread.start(); break; case R.id.bt_second2: //因为handler需要时间创建,因此不能直接将下面的代码放在 //thread.start();下面,放在他下面会报空指针 thread.handler.sendEmptyMessage(0); break; default: break; } // thread.handler.sendEmptyMessage(0); } class Mythread extends Thread{ private Handler handler; @Override public void run() { //handler—send-MessageQueue-looper读取—hangleMessage操作 //looper是主线程中默认使用,因此在子线程向主线程发消息的时候没有添加 //但是子线程不具有,因此必须写出 Looper.prepare(); handler=new Handler(){ @Override public void handleMessage(Message msg) { Log.d("主线程给子线程", "主线程给子线程"); } }; Looper.loop(); } } }
相关文章推荐
- angular-ueditor修正版发布
- Lync Server 2013 Prerequisite installation failed 推荐
- LINQ语句中的.AsEnumerable() 和 .AsQueryable()的区别
- 理解Android中dpi和分辨率的关系,谈谈Android做成适应全部手机的UI方式
- quick中触摸事件响应机制
- keychain + uuid != uuid
- iOS开发之UITextView,设置textViewplaceholder
- iOS开发之UITextView,设置textViewplaceholder
- easyui filebox 浏览图片
- 163邮件出错:不允许使用邮箱名称。 服务器响应为: authentication is required,smtp7,C8CowEDpS0+Uke9VvSmXBg--.546S2 1441763733
- 文件的特殊权限:SUID SGID SBIT
- select, iocp, epoll,kqueue及各种I/O复用机制
- Leetcode 115 Distinct Subsequences 解题报告
- iOS UINavigationController与UITabBarController的组合使用
- 开源项目分析之UIL(续)
- UICollectionView 高级进阶篇
- Java build模式
- iOS 提交代码出现提示弹出框显示 “A commit message is required to perform this operation.Enter a commit message and try again.“
- JSP页面中的标签以及内置对象request等
- 解决pycharm无法提示pyqt4.QtGui但是可以运行的问题