Android IPC之Messenger源码分析
程序员文章站
2022-05-07 22:06:44
android ipc之messenger分析,在android ipc之messenger一文中,对通过messenger实现ipc的流程做了一个简单的介绍,在文中曾说到me...
android ipc之messenger分析,在android ipc之messenger一文中,对通过messenger实现ipc的流程做了一个简单的介绍,在文中曾说到messenger的底层也是通过aidl实现的,这里通过messenger的源码来看看aidl是如何实现messenger的。
messenger实现ipc流程分析
messenger源码分析
package android.os; public final class messenger implements parcelable { /** * imessenger就是通过声明一个.aidl文件生成的对应的接口 */ private final imessenger mtarget; /** * 第一步:在服务端创建messenger * * 通过该方法创建一个messenger对象,该对象会持有一个handler的引用, * 所有要通过messenger的send()发送的跨进程message,最终都是通过该handler发送, * 所以handler是messenger实现跨进程通信的核心类之一 */ public messenger(handler target) { mtarget = target.getimessenger(); } /** * 第二步:将binder对象返回到客户端 * * 通过调用该方法返回一个binder对象,这个一般在service的onbind()方法中返回ibinder对象时调用。 */ public ibinder getbinder() { return mtarget.asbinder(); } /** * 第三步:客户端服务绑定成功后,通过binder对象创建messenger * * 通过binder对象创建一个messenger对象, * 这个构造方法一般在客户端调用,当绑定服务成功后, * 通过返回的binder对象创建的messenger会和服务端的messenger对象对应 * 最终在客户端发送消息在服务端可以接收到。 * */ public messenger(ibinder target) { mtarget = imessenger.stub.asinterface(target); } /** * 第四步:在客户端调用send方法,向服务端发送消息 * * 通过调用该方法,最终通过handler的send()方法,发送message消息 */ public void send(message message) throws remoteexception { mtarget.send(message); } public boolean equals(object otherobj) { if (otherobj == null) { return false; } try { return mtarget.asbinder().equals(((messenger)otherobj) .mtarget.asbinder()); } catch (classcastexception e) { } return false; } public int hashcode() { return mtarget.asbinder().hashcode(); } public int describecontents() { return 0; } public void writetoparcel(parcel out, int flags) { out.writestrongbinder(mtarget.asbinder()); } public static final parcelable.creator creator = new parcelable.creator() { public messenger createfromparcel(parcel in) { ibinder target = in.readstrongbinder(); return target != null ? new messenger(target) : null; } public messenger[] newarray(int size) { return new messenger[size]; } }; public static void writemessengerornulltoparcel(messenger messenger, parcel out) { out.writestrongbinder(messenger != null ? messenger.mtarget.asbinder() : null); } public static messenger readmessengerornullfromparcel(parcel in) { ibinder b = in.readstrongbinder(); return b != null ? new messenger(b) : null; } }
在上面的源码中,messenger定义了一个imessenger类型的成员变量mtarget,但是在java源码中看不到imessenger类的相关信息,这是因为imessenger是一个声明的aidl接口,我们可以通过android源码找到这个aidl接口文件,代码如下:
/** *文件路径: * * ../android-6.0.1_r72/frameworks/base/core/java/android/os/imessenger.aidl */ package android.os; import android.os.message; /** @hide */ oneway interface imessenger { void send(in message msg); }
在上面的源码中,我们可以看到imessenger对象mtarget对象的初始化是通过调用 handler.getimessenger()完成的。
public messenger(handler target) { mtarget = target.getimessenger(); }
这里我们看下handler中的getimessenger方法。
final imessenger getimessenger() { synchronized (mqueue) { if (mmessenger != null) { return mmessenger; } mmessenger = new messengerimpl(); return mmessenger; } } /** * 最终,messenger的send()方法,是在这里实现的, * 这里我们可以确实,messenger实现ipc是通过handler实现的 */ private final class messengerimpl extends imessenger.stub { public void send(message msg) { // 这是一个本地方法,用于获取进程的uid,保证在进程间通信 msg.sendinguid = binder.getcallinguid(); // 调用handler的sendmessage方法实现ipc handler.this.sendmessage(msg); }
这里,我们可以得出一个结论messenger实现ipc的流程,底层是通过aidl文件实现的,同时handler也是messenger实现ipc的关键类。
关于handler,想必大多数人对于handler的认识是停留在线程间通信的,至于handler如何实现ipc这里只提一句,handler在native层中通过管道实现ipc通信。
上一篇: 中学生美文摘抄
下一篇: 关羽非常勇武,为何会被小将纪灵击败呢?