原理

/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package android.os;

/**
* Reference to a Handler, which others can use to send messages to it.
* This allows for the implementation of message-based communication across
* processes, by creating a Messenger pointing to a Handler in one process,
* and handing that Messenger to another process.
*
* <p>Note: the implementation underneath is just a simple wrapper around
* a {@link Binder} that is used to perform the communication. This means
* semantically you should treat it as such: this class does not impact process
* lifecycle management (you must be using some higher-level component to tell
* the system that your process needs to continue running), the connection will
* break if your process goes away for any reason, etc.</p>
*/
public final class Messenger implements Parcelable {
private final IMessenger mTarget;

/**
* Create a new Messenger pointing to the given Handler. Any Message
* objects sent through this Messenger will appear in the Handler as if
* {@link Handler#sendMessage(Message) Handler.sendMessage(Message)} had
* been called directly.
*
* @param target The Handler that will receive sent messages.
*/
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}

/**
* Send a Message to this Messenger's Handler.
*
* @param message The Message to send. Usually retrieved through
* {@link Message#obtain() Message.obtain()}.
*
* @throws RemoteException Throws DeadObjectException if the target
* Handler no longer exists.
*/
public void send(Message message) throws RemoteException {
mTarget.send(message);
}

/**
* Retrieve the IBinder that this Messenger is using to communicate with
* its associated Handler.
*
* @return Returns the IBinder backing this Messenger.
*/
public IBinder getBinder() {
return mTarget.asBinder();
}

/**
* Comparison operator on two Messenger objects, such that true
* is returned then they both point to the same Handler.
*/
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<Messenger> CREATOR
= new Parcelable.Creator<Messenger>() {
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];
}
};

/**
* Convenience function for writing either a Messenger or null pointer to
* a Parcel. You must use this with {@link #readMessengerOrNullFromParcel}
* for later reading it.
*
* @param messenger The Messenger to write, or null.
* @param out Where to write the Messenger.
*/
public static void writeMessengerOrNullToParcel(Messenger messenger,
Parcel out) {
out.writeStrongBinder(messenger != null ? messenger.mTarget.asBinder()
: null);
}

/**
* Convenience function for reading either a Messenger or null pointer from
* a Parcel. You must have previously written the Messenger with
* {@link #writeMessengerOrNullToParcel}.
*
* @param in The Parcel containing the written Messenger.
*
* @return Returns the Messenger read from the Parcel, or null if null had
* been written.
*/
public static Messenger readMessengerOrNullFromParcel(Parcel in) {
IBinder b = in.readStrongBinder();
return b != null ? new Messenger(b) : null;
}

/**
* Create a Messenger from a raw IBinder, which had previously been
* retrieved with {@link #getBinder}.
*
* @param target The IBinder this Messenger should communicate with.
*/
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
}
这时候我们在回头看两个构造方法:

1. public Messenger(Handler target) {
mTarget = target.getIMessenger();
}


2. public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
 两个构造方法内部都是初始化对象 mTarget:

private final IMessenger mTarget;
再看看 IMessenger,是一个AIDL文件:

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/os/IMessenger.aidl

/* //device/java/android/android/app/IActivityPendingResult.aidl
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

package android.os;

import android.os.Message;

/** @hide */
oneway interface IMessenger {
void send(in Message msg);
}
在看看Handler 中的部分代码:

final IMessenger getIMessenger() {
synchronized (mQueue) {
if (mMessenger != null) {
return mMessenger;
}
mMessenger = new MessengerImpl(http://www.amjmh.com/v/BIBRGZ_558768/);
return mMessenger;
}
}

private final class MessengerImpl extends IMessenger.Stub {
public void send(Message msg) {
msg.sendingUid = Binder.getCallingUid();
Handler.this.sendMessage(msg);
}
}
从以上代码,可以看出Messenger又跟Binder联系起来了。 最终还是AIDL文件来完成的,只不过Messenger进行了深度的封装AIDL,使用起来更简单。

posted on 2019-09-12 17:25  激流勇进1  阅读(279)  评论(0编辑  收藏  举报