7.1 基础知识Android消息处理机制
1. Android消息处理机制: Handler, MessageQueue, Looper, Thread
线程概念 : 一个应用程序运行时它的主体被称为进程,
一个进程内部可以有多个线程,
线程共享进程的资源
线程间通信
在android系统中是怎么封装通讯的,假如存在两个线程A和B,如果A线程要告诉B线程一些消息,怎么实现?
A进程怎么发发消息?(1)构造消息,消息里面有数据信息和处理函数(2)发消息;这两个步骤在android源码中被封装成Handler
消息在android中被封装为Message,A发送Message给B,可能B处理不过来,因此A把消息放到B进程里面的消息队列MessageQueue类,在B进程的循环体中做什么事?
(1)、从队列中取出消息;(2)处理消息,执行消息的处理函数;这两个步骤在android源码中被封装成Looper
Looper源码在frameworks/base/core/java/android/os/Looper.java
Handler源码在frameworks/base/core/java/android/os/Handler.java //ctrl+shift+n在输入handler.java来打开
a. 创建MessageQueue: Looper.prepare()
b. 使用Handler构造、发送Message
b.1 new Handler //创建handler的时候可以指定Looper即消息接受者和Callback回调函数即消息的处理函数,如果不知道肯定有默认的Looper和消息处理函数
b.2 Handler.sendMessage, sendEmptyMessageAtTime, sendMessageDelayed
c. 使用Looper循环处理消息:在loop函数中有个for死循环
c.1 从MessageQueue中取出Message,//Message msg = queue.next();
c.2 执行它的处理函数: msg.target.dispatchMessage(msg)//target就是Handler,dispatchMessage会调用处理函数
应用程序编写:
功能说明:app中创建一个button,创建子线程,添加消息处理功能,并且给Button添加处理函数,并且主线程会监测button,当button按下时给子线程发送消息,子线程收到消息后打印出来
import android.view.View;
import android.util.Log;//打印导入的库
public class MainActivity extends AppCompatActivity{
private Button mButton;
private final String TAG = "MessageTest";
private int ButtonCount = 0;
private Thread myThread;
private MyThread myThread2;
private Handler mHandler;
private int mMessageCount = 0;
class MyRunnable:implements Runable{
int count=0;
public void run(){
for(;;){
Log.d(TAG,"MyThread"+(count++));
try{
Thread.sleep(3000);
}catch(INterrupteException e){
e.printStackTrace();
}
}
}
}
class Mythread extends Thread{ //android只带的消息处理是在HandlerThread.java中,其功能同我们怎么的Mythread,如果不自己创建Mythread,可以直接使用HandlerThread类
public void run(){
super.run();
Looper.prepare();//创建消息队列
Looper.loop();//从消息队列中取出消息,调用消息的处理函数
}
public Looper getLooper(){
return Looper.myLooper();
}
}
pretected void onCreate(Bundle savedInstanceState){
........
........
mButton = (Button)findViewById(R.id.button);//双击Button,按下shift+F1,可以查看类的帮助文档
mButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
Log.d(TAG,"SendMessage"+(ButtonCount++) );
Message msg = new Message();
mHandler.sendMessage(msg );//发送消息的会从把消息放到消息队列中,消息队列是从handler创建的时候从Looper中获得
}
});
myThread = new Thread(new MyRunnable,"MessageTestThread");//(runnable接口的方法run是线程的主体函数)
myThread.start();
myThread2 = new MyThread();
myThread2 .start();//功能和myThread一样,start会导致MyThread的run函数被执行,run函数会执行Looper.prepare()去创建消息队列,但这个函数并不一定马上就执行,如果住进程中创建Handler的时候没有队列,会存在风险,所以修改class MyThread extends Thread{}
////我们现在的代码里面有三个线程了,主线程、myThread和myThread2,,要确定消息发给谁Looper
mHandler = new Handler(myThread2.getLooper(),new Handler.Callback(){
public boolean handleMessage(Message msg){
Log.d(TAG,"getMessage"+(mMessageCount++))
return false;
}
});
}
}
针对上面所说的风险修改class MyThread extends Thread{},如下:
class MyThread extends Thread{
private Looper mLooper;
public void run(){
super.run();
Looper.prepare();//创建消息队列
mLooper = Looper.myLooper();
notifyAll();//当主线程调用getLooper,在mLooper 为空的时候会休眠,所以这里需要唤醒休眠的线程
Looper.loop();//从消息队列中取出消息,调用消息的处理函数
}
public Looper getLooper(){
if(!isAlive()){
return null;
}
synchronized(this){
while(isAlive() && mLooper == null){
try{
wait();
}catch (InterruptedException e){
}
}
}
return mLooper;
}
}
修改代码使用系统只带的消息处理线程:
1、导入包:import android.os.HandlerThread;
2、在public class MainActivity extends AppCompatActivity中新增
private HandlerThread myThread3;
private Handler mHandler3;
myThread3 = new HandlerThread("MessageTestThread3");
myThread3 .start();
mHandler3 = new Handler(myThread3.getLooper());
在button的onClick函数中添加:
mHandler3.post(new Runnable(){
public void run(){
Log.d(TAG,"getMessage for Thread3"+(mMessageCount++));
}
});
7.1 基础知识Android消息处理机制的更多相关文章
- 【Android 开发】: Android 消息处理机制之一: Handler 与 Message
最近几讲内容,我们学习了Android中关于多线程的一些知识,上一讲我们讲解了异步任务 AsyncTask 的操作,Android中还提供了其他的线程操作,如Handler Message Messa ...
- (转)Android消息处理机制(Handler、Looper、MessageQueue与Message)
转自 http://www.cnblogs.com/angeldevil/p/3340644.html Android消息处理机制(Handler.Looper.MessageQueue与Messag ...
- Android消息处理机制
Android消息处理机制 Android应用程序消息处理机制(深入到native,实际由管道实现-pipe&epoll)
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
解析Android消息处理机制 ——Handler/Thread/Looper & MessageQueue Keywords: Android Message HandlerThread L ...
- Android架构分析之Android消息处理机制(二)
作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Android版本号:4.4.2 在上一篇文章中我们看了一个使用Handler处理Message消息的样例,本文我们 ...
- Android架构分析之Android消息处理机制(一)
作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Android版本号:4.4.2 在这个系列文章中我们将来分析Android消息处理机制. 本文介绍了一个使用Han ...
- Android消息处理机制(Handler 与Message)---01
一.handler的使用场景为么会有handler?(部分内容图片摘自http://www.runoob.com/w3cnote/android-tutorial-handler-message.ht ...
- [旧][Android] 消息处理机制
备注 原发表于2016.06.06,资料已过时,仅作备份,谨慎参考 概述 Android 的消息处理机制主要是指 Handler 的运行机制以及 Handler 所附带的 MessageQueue 和 ...
- 【Android】Android消息处理机制
三大核心类 android的消息处理有三个核心类:Looper,Handler和Message. 其实还有一个Message Queue(消息队列),但是MQ被封装到Looper里面了 Looper ...
随机推荐
- 版本号控制-搭建gitserver
GitHub是一个免费托管开源码的Gitserver,假设我们不想公开项目的源码,又不想付费使用.那么我们能够自己搭建一台Gitserver. 以下我们就看看,怎样在Ubuntu上搭建Gitserve ...
- 56.ERR! configure error gyp ERR! stack Error: Can't find Python executable "python", you can set the PYTHON env variable.
Node.js 在安装模块的时候报错,缺少python环境. ERR! configure error gyp ERR! stack Error: Can't find Python executab ...
- es6 --- var const let
var const let 区别 今天第一次遇到const定义的变量,查阅了相关资料整理了这篇文章.主要内容是:js中三种定义变量的方式const, var, let的区别. 1. const ...
- Fragment-如何监听fragment中的回退事件与怎样保存fragment状态
一.如何监听Fragment中的回退事件 1.问题阐述 在Activity中监听回退事件是件非常容易的事,因为直接重写onBackPressed()函数就好了,但当大家想要监听Fragment中的回退 ...
- 用console.log分析Vue源码
前言 本文通过console.log的一些特性,结合vue.js的源码,通过一个简单的例子,让你了解Vue的各个过程的变化. 控制台输出的效果图 请用chrome查看,并打开控制台看效果 演示地址 准 ...
- 谈一谈Nginx的强大
什么是Nginx? Nginx是一款高性能,开源的,支持高并发而轻量级的Web服务器,同时也是具有反向代理服务器及电子邮件(IMAP/POP3)的代理服务器. 基于REST架构风格,并且以统一资源描述 ...
- SVN无法提交,路径找不到问题的解决方案
自己有了个云服务器,只在上面搭建了几个博客网站(小雷网等). 我自己的代码,保存在SVNChina上,每年99元.(私人的付费,开源的免费) 云服务器,闲着也是闲着,决定在上面搭建一个属于自己的SVN ...
- Repractise基础篇:Web应用开发七日谈
Repractise基础篇:Web应用开发七日谈 本来想的仅仅是画一个例如以下的七日图来说说Web开发的.随后又想了想这似乎是一个非常棒的Web开发相关的知识介绍.应用开发是一个非常有意思的循环,多数 ...
- PHP中字符串比较的常用方法
PHP中字符串比较的常用方法 一.总结 1.其实应该是直接等于号就可以了的 2.也可用strcmp,注意返回值 二.PHP中字符串比较的常用方法 1.按字节比较 按字节比较字符串是最常用的方法.其中可 ...
- Project Euler 389 Platonic Dice (概率)
题目链接: https://projecteuler.net/problem=389 题意: 掷一个正四面体骰子,记点数为\(T\). 掷\(T\)个正六面体骰子,记点数和为\(C\). 掷\(C\) ...