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<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];
        }
    };


    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通信

這裏推薦一篇關於Handler Native層的講解: Android消息機制2-Handler(Native層)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章