android应用程序消息处理机制之消息发送
来源:互联网 发布:购买ET软件 编辑:程序博客网 时间:2024/06/06 01:09
2、消息的发送
应用程序的主线程准备好消息队列并且进入到消息循环后,其他地方就可以往这个消息队列发送消息了。
查看那ActivityThread。java中的scheduleLaunchActivity() ,这里就先以启动一个activity,
然后发送消息这个例子来入手吧,之后再看看一般我们自己建的handler的处理。
scheduleLaunchActivity(...){
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profileFile = profileName;
r.profileFd = profileFd;
r.autoStopProfiler = autoStopProfiler;
updatePendingConfiguration(curConfig);
queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
}
相关参数封装成一个ActivityClientRecord对象r ,然后使用queueOrSendMessage
往消息队列中加入一个新的消息(标记为:H.LAUNCH_ACTIVITY)
2.1、查看queueOrSendMessage(H.LAUNCH_ACTIVITY, r)
private final void queueOrSendMessage(int what, Object obj) {
queueOrSendMessage(what, obj, 0, 0);
}
......
private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
synchronized (this) {
......
//封装之前传递过来的信息Message对象msg
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
//加入到消息队列中,这里的mH为ActivityThread的成员变量,类型是H,继承自Handler。
//这个mH对象,在我们前面第一步骤,实现消息循环时,创建ActivityThread的时候
//就创建了。
mH.sendMessage(msg);
}
}
针对这个mH还是有必要的仔细说清楚
public final class ActivityThread {
......
public static final void main(String[] args) {
......
ActivityThread thread = new ActivityThread();
thread.attach(false);
......
}
}
紧接着看看H这个类
public final class ActivityThread {
......
final H mH = new H();
......
private final class H extends Handler {
......
public void handleMessage(Message msg) {
......
switch (msg.what) {
......
}
......
}
}
由于H是继承自Handler的,所以在构造H的时候,也会调用Handler的构造函数
public class Handler{
public Handler(){
......
//获取Looper对象,这里获取到的则是前面在实现消息循环时
//调用Looper.prepareMainLooper()创建的。
mLooper = Looper.myLooper();
......
//使用获取的Looper来访问消息队列
mQueue = mLooper.mQueue;
}
......
final MessageQueue mQueue;
final Looper mLooper;
......
}
回到前面的mH.sendMessage(msg),实际上调用的是mH的父类Handler的sendMessage(msg)
public final boolean sendMessage(Message msg)
{
//接着
return sendMessageDelayed(msg, 0);
}
---->
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
//在接着
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
---->
public boolean sendMessageAtTime(Message msg, long uptimeMillis)
{
boolean sent = false;
MessageQueue queue = mQueue;
if (queue != null) {
//设置消息的目标对象,即这个消息由谁来处理。
//这里的this表示这个消息最终由这个Handler来处理
//即由ActivityThread对象的mH成员变量来处理。
msg.target = this;
//这里的uptimeMillis传递进来为当前系统时间+0 ,表示立即处理,不需要延迟
//接下来就是调用这个方法来实现添加消息到消息队列去了
sent = queue.enqueueMessage(msg, uptimeMillis);
}
else {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
}
return sent;
}
final boolean enqueueMessage(Message msg, long when) {
......
final boolean needWake;
synchronized (this) {
......
msg.when = when;
//Log.d("MessageQueue", "Enqueing: " + msg);
Message p = mMessages;
//把消息添加到消息队列,有两种方式:
if (p == null || when == 0 || when < p.when) {
//消息队列为空,主线程出于空闲等待状态,需要唤醒它。
msg.next = p;
mMessages = msg;
//这里的mBlocked 在上面的next()进去空闲等待的时候,mBlocked = true
needWake = mBlocked; // new head, might need to wake up
} else {
//消息队列不为空,不需要唤醒主线程,因为它正忙着处理其他消息呢。
//但是新加入的消息,要按照消息执行的时间进行排队。
Message prev = null;
while (p != null && p.when <= when) {
prev = p;
p = p.next;
}
msg.next = prev.next;
prev.next = msg;
needWake = false; // still waiting on head, no need to wake up
}
}
if (needWake) {
nativeWake(mPtr); //唤醒主线程的操作,调用JNI操作
}
return true;
}
接着到JNI层
void NativeMessageQueue::wake() {
mLooper->wake(); //没想到调用的是freameworks层中Looper的wake()
}
最后到C++层【freameworks】
void Looper::wake() {
......
ssize_t nWrite;
do {
nWrite = write(mWakeWritePipeFd, "W", 1);
} while (nWrite == -1 && errno == EINTR);
.......
}
wake()主要是文件描述符mWakeWritePipeFd往管道写入一个"W"字符串。
往管道写入内容的目的是为了唤醒应用程序的主线程。前面我们在分析应用程序的消息循环时说到,
当应用程序的消息队列中没有消息处理时,应用程序的主线程就会进入空闲等待状态,
而这个空闲等待状态就是通过调用这个Looper类的pollInner函数来进入的,
具体就是在pollInner函数中调用epoll_wait函数来等待管道中有内容可读的。
这时候既然管道中有内容可读了,
应用程序的主线程就会从这里的Looper类的pollInner函数返回到JNI层的nativePollOnce函数,
最后返回到Java层中的MessageQueue.next函数中去,这里它就会发现消息队列中有新的消息需要处理了,
于就会处理这个消息。
- android应用程序消息处理机制之消息发送
- android应用程序消息处理机制分析之消息处理
- Android应用程序消息处理机制Handler分析
- 浅谈Android应用程序键盘消息处理机制
- 浅谈Android应用程序键盘消息处理机制
- 浅谈Android应用程序键盘消息处理机制
- Android应用程序的消息处理机制
- adnroid_Handler消息发送处理机制
- Windows应用程序消息处理机制
- Android 消息处理机制
- Android消息处理机制
- Android消息处理机制
- android消息处理机制
- android 消息处理机制
- Android消息处理机制
- Android消息处理机制
- Android消息处理机制
- Android消息处理机制
- Java方法的声明及使用
- UITableView 添加 下拉刷新(EGORefreshTableHeaderView)
- Java正则表达式入门
- 串行口控制寄存器(SCON)(转载自百度文库)
- 前缀表达式
- android应用程序消息处理机制之消息发送
- java导出excel java操作文件。文件夹 java制作zip
- Android4.1 settings中添加一个新选项
- HASP多语言云计算开发框架白皮书
- android UI高仿
- hdu 2504
- APT攻击——从韩国大规模MBR攻击中学到的三个教训
- 我,一个写代码的
- Lucene