浅谈Android的Message机制 androidMessagejava
程序员文章站
2022-05-16 12:23:03
...
在Android的Message里面有这几个比较重要的类:
Looper,Handler,MessageQueue,Message
当然这里面还有一个类ThreadLocal,不过我就不去深入的进行这个类的剖析。
Message说白了就是一个线程往另外一个线程发送消息。让另外一个消息根据传递过来的Message对象进行相关的操作。也就是实现了多线程之间的通讯。
过程是让一个线程拥有一个Looper,看名字是不是很熟悉?是循环的意思,这个类用来遍历里面的成员变量MessageQueue,这个消息队列里面有消息,则拿出来处理。这里是个死循环,唯一的目的就是监听消息队列。
另外一个线程仅仅负责把Message放到MessageQueue里面就可以了
再说一下他们的关系,一个线程有且只能拥有一个Looper,一个Looper有且只有一个MessageQueue
先看线程1:就是负责监听消息队列的线程
这个handler是一个从Handler衍生出来的子类
我们可以重写父类的handleMessage方法来按自己的逻辑需求处理。
回到上面的代码片段。
Looper.getMainLooper()执行了之后,源码里面说安卓会自动执行prepareMainLooper()方法,这个具体怎么实现的就不管他了。一个代码片段里面只要代码包含在Looper的prepare()和loop()中间,这个线程就拥有了一个Looper。而prepareMainLooper里面就执行了prepare(boolean)这个方法。这里面只有两个逻辑:
1.把这个looper和当前线程进行捆绑
2.new一个MessageQueue对象出来给Looper
接着进行这个操作
把looper交给handler
在这里我们并不需要显式的去Looper.loop();可能也是因为安卓环境自动执行的吧。Looper.loop()方法主要是遍历MessageQueue,看这个消息队列里面有没有要处理的Message。有的话就拿出来处理。这是个怎么处理过程呢?我看了下源码是这样的:说道这里就不得不说Message了。Message里面有个成员变量
好了,再回到执行的过程,Looper.loop()会死循环这个队列,然后执行 msg.target.dispatchMessage(msg);说多了会晕,那么意思就是Handler里面会有一个方法dispatchMessage(msg),看一下Handler的源码,程序会执行handleMessage(msg);这个就是处理过程,我们唯一做的就是在衍生自Handler的这个类里面重写这个方法。就可以按照我们的意愿去处理业务逻辑。
说的通俗易懂的就是一个线程里面有一个Looper。Looper什么都不干,就看MessageQueue里面有没有Message。有的话就拿出来处理。就干这些事情。
另外一个线程要跟上面的线程通讯只需要给这个消息队列里面添加消息就可以了。
我们使用handler.obtainMessage();从消息池里面看有没有可用的消息,有的话就直接拿出来一个Message。没有的话系统会new一个返回给我们。而执行这个方法的时候Message就会把我们等这个handler跟Message绑定了。也就是上面提到的Message里面的Target。
然后在执行handler.sendMessage(msg);执行这个的时候不要被现象蒙蔽。他不是直接发送消息,而是给消息队列里面添加Message。可能设计者的初衷就是说往消息队列里面添加Message的吧。给消息队列发送完了之后,然后线程1还在不停的loop()。但是这个时候他发现了MessageQueue里面有Message。所以就拿出来处理。
关于MessageQueue里面的指针,取值什么的这里就不说了。这里只是说一个大概的处理流程。让自己mark一下。如果不对,希望有心之人加以指正。
Looper,Handler,MessageQueue,Message
当然这里面还有一个类ThreadLocal,不过我就不去深入的进行这个类的剖析。
Message说白了就是一个线程往另外一个线程发送消息。让另外一个消息根据传递过来的Message对象进行相关的操作。也就是实现了多线程之间的通讯。
过程是让一个线程拥有一个Looper,看名字是不是很熟悉?是循环的意思,这个类用来遍历里面的成员变量MessageQueue,这个消息队列里面有消息,则拿出来处理。这里是个死循环,唯一的目的就是监听消息队列。
另外一个线程仅仅负责把Message放到MessageQueue里面就可以了
再说一下他们的关系,一个线程有且只能拥有一个Looper,一个Looper有且只有一个MessageQueue
先看线程1:就是负责监听消息队列的线程
Looper looper = Looper.getMainLooper(); handler = new ServiceHandler(looper);
这个handler是一个从Handler衍生出来的子类
我们可以重写父类的handleMessage方法来按自己的逻辑需求处理。
回到上面的代码片段。
Looper.getMainLooper()执行了之后,源码里面说安卓会自动执行prepareMainLooper()方法,这个具体怎么实现的就不管他了。一个代码片段里面只要代码包含在Looper的prepare()和loop()中间,这个线程就拥有了一个Looper。而prepareMainLooper里面就执行了prepare(boolean)这个方法。这里面只有两个逻辑:
1.把这个looper和当前线程进行捆绑
2.new一个MessageQueue对象出来给Looper
接着进行这个操作
handler = new ServiceHandler(looper);
把looper交给handler
在这里我们并不需要显式的去Looper.loop();可能也是因为安卓环境自动执行的吧。Looper.loop()方法主要是遍历MessageQueue,看这个消息队列里面有没有要处理的Message。有的话就拿出来处理。这是个怎么处理过程呢?我看了下源码是这样的:说道这里就不得不说Message了。Message里面有个成员变量
Handler target;
好了,再回到执行的过程,Looper.loop()会死循环这个队列,然后执行 msg.target.dispatchMessage(msg);说多了会晕,那么意思就是Handler里面会有一个方法dispatchMessage(msg),看一下Handler的源码,程序会执行handleMessage(msg);这个就是处理过程,我们唯一做的就是在衍生自Handler的这个类里面重写这个方法。就可以按照我们的意愿去处理业务逻辑。
说的通俗易懂的就是一个线程里面有一个Looper。Looper什么都不干,就看MessageQueue里面有没有Message。有的话就拿出来处理。就干这些事情。
另外一个线程要跟上面的线程通讯只需要给这个消息队列里面添加消息就可以了。
我们使用handler.obtainMessage();从消息池里面看有没有可用的消息,有的话就直接拿出来一个Message。没有的话系统会new一个返回给我们。而执行这个方法的时候Message就会把我们等这个handler跟Message绑定了。也就是上面提到的Message里面的Target。
然后在执行handler.sendMessage(msg);执行这个的时候不要被现象蒙蔽。他不是直接发送消息,而是给消息队列里面添加Message。可能设计者的初衷就是说往消息队列里面添加Message的吧。给消息队列发送完了之后,然后线程1还在不停的loop()。但是这个时候他发现了MessageQueue里面有Message。所以就拿出来处理。
关于MessageQueue里面的指针,取值什么的这里就不说了。这里只是说一个大概的处理流程。让自己mark一下。如果不对,希望有心之人加以指正。
推荐阅读
-
Android开发的广播机制讲解
-
浅谈Android中适配器的notifyDataSetChanged()为何有时不刷新
-
Android开发的广播机制讲解
-
浅谈Android获取ImageView上的图片,和一个有可能遇到的问题
-
浅谈Android注解在日常开发中的简单使用
-
Android中ACTION_CANCEL的触发机制与滑出子view的情况
-
Android的线程通信:消息机制原理(Message,Handler,MessageQueue,Looper),异步任务AsyncTask,使用JSON
-
浅谈Python的垃圾回收机制
-
详解Android Scroller与computeScroll的调用机制关系
-
浅谈Android开发中ListView控件性能的一些优化方法