AIDL思路梳理

寫在前面

本文主要是我個人的理解思路方式。趁著還清晰,所記錄的。如果哪位朋友讀了兩句不合胃口(因為主要是梳理思路,可能我寫這個的時候默認一些東西了,就沒寫出來)。建議讀下我下面參考文章里的文章。最后一篇文章是介紹Web模塊獨立進程實現(xiàn)的。本文里的代碼。也是基于此的。感謝建良。
AIDL。Android Interface Definition Language,也就是Android接口定義語言。
那么實際上就跟接口回調一樣。客戶端拿到服務端的接口。然后操作。
本文結合項目中H5進程與主進程的通信進行梳理。主要有js調用接口后到主進程。還有h5監(jiān)聽到某種頁面后,做一些通知處理
比如,如果發(fā)現(xiàn)url中有callback字樣。則通知主進程發(fā)送一個eventbus。然后對應的地方接收進行操作,
第一步。寫.aidl 文件。


image.png

并在里面聲明我們需要的方法。編譯器會自動生成一個對應的.java文件。如下


image.png


可以看到里面有一個抽象類Stub繼承了Binder,并且實現(xiàn)了我們一開始.aidl的接口。那我們再寫一個類來繼承這個Stub。就可以作為實現(xiàn)類,類進行響應一些方法的調用。如下


image.png

第二步。寫主進程的服務端,用于客戶端來連接
image.png

Service有了然后就是binderService。連接服務,有個參數(shù)是ServiceConnection,然后回調方法onServiceConnected,方法連接后會返回一個IBinder對象。


image.png

通過IBinderManager.Stub.asInterface(service) . 客戶端拿到了服務端(主進程)返回的binder。

注意點

mBinderManager = IBinderManager.Stub.asInterface(service)這里。
對于Binder IPC的過程中, 同一個進程的調用則會是asInterface()方法返回的便是本地的Binder對象;對于不同進程的調用則會是遠程代理對象BinderProxy. 下面是系統(tǒng)自動生成的對應aidl的類。發(fā)現(xiàn)
跟學習Activity啟動流程的跨進程很相似。具體看注釋

//子進程請求主進程服務成功后,返回這個管理器Binder,在子進程可以根據(jù)binderCode拿到需要的Binder
//這種設計是為了解耦,方便不同業(yè)務下把Binder分離

public interface IBinderManager extends android.os.IInterface {

    //本地

    /** Local-side IPC implementation stub class. */
    public static abstract class Stub extends android.os.Binder implements com.silvrr.common.IBinderManager {

        private static final java.lang.String DESCRIPTOR = "com.silvrr.common.IBinderManager";

        /** Construct the stub at attach it to the interface. */
        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

        /**
         * Cast an IBinder object into an com.silvrr.common.IBinderManager interface,
         * generating a proxy if needed.
         */
        public static com.silvrr.common.IBinderManager asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof com.silvrr.common.IBinderManager))) {
                return ((com.silvrr.common.IBinderManager) iin);
            }
            //這個方法在下面
            return new com.silvrr.common.IBinderManager.Stub.Proxy(obj);
        }

        @Override
        public android.os.IBinder asBinder() {
            return this;
        }

        @Override
        public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags)
                throws android.os.RemoteException {
            switch (code) {
                case INTERFACE_TRANSACTION: {
                    reply.writeString(DESCRIPTOR);
                    return true;
                }
                case TRANSACTION_queryBinder: { //跟下面發(fā)送的一樣。因為是抽象類。所以到這里后,具體實現(xiàn)就會調用實現(xiàn)類
                    //即BinderManager
                    data.enforceInterface(DESCRIPTOR);
                    int _arg0;
                    _arg0 = data.readInt();
                    android.os.IBinder _result = this.queryBinder(_arg0);
                    reply.writeNoException();
                    reply.writeStrongBinder(_result);
                    return true;
                }
            }
            return super.onTransact(code, data, reply, flags);
        }

        //服務端在客戶端的代理
        private static class Proxy implements com.silvrr.common.IBinderManager {

            private android.os.IBinder mRemote;

            Proxy(android.os.IBinder remote) {
                //這個remote就跟Activity啟動流程里。
                // 可知mRemote便是指向服務端的binder/BinderProxy對象
                mRemote = remote;
            }

            @Override
            public android.os.IBinder asBinder() {
                return mRemote;
            }

            public java.lang.String getInterfaceDescriptor() {
                return DESCRIPTOR;
            }

            //aidl里聲明的方法
            @Override
            public android.os.IBinder queryBinder(int binderCode) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                android.os.IBinder _result;
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeInt(binderCode);
                    //這里層層下去最后到了binder驅動,然后再一層層回來。
                    // 底層到了共享內存。然后就再一層層調用了另一個進程(服務進程)的ontransact方法,
                    // 然后里面會調用我們的具體的方法。 proxy中transact就跟ActivityManagerProxy中一樣。
                    // 最終到了AMN即AMS的onTransact中 ,本方法在上面。該內部類的外面stub中。
                    mRemote.transact(Stub.TRANSACTION_queryBinder, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readStrongBinder();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }
        }

        static final int TRANSACTION_queryBinder = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    }

    public android.os.IBinder queryBinder(int binderCode) throws android.os.RemoteException;
}

借用Service啟動的一個圖


image.png

總結

在重復幾句。
通過asInterface,將服務端的binder傳過來(service綁定后返回的,實際上是服務端binder的代理BinderPoxy),返回一個new Proxy(上面代碼中proxy)。這個proxy就是服務端在客戶端的代理了。因為這個代理里面把我們傳過來的binder賦給了一個mRemote對象。所以我們在調用我們子進程的方法,比如


image.png

比如調用mBInderManger的方法的時候。因為這個mBIndermanaer在asInterface時返回的就是上面這個proxy的對象。所以,就調用了proxy里面的queryBinder方法。


image.png

然后如注釋中說的。然后結合上面的圖。會一層層最后調用了
image.png

。

應該是比較清楚了??蛻舳诉B接service。然后返回一個binder??蛻舳送ㄟ^這個binder,拿到一個服務端的代理。 然后客戶端要進行操作了。直接調用對應的方法,該方法里直接調用了服務端(mRemote)的

transact方法。這就到了Binder里。binder又層層的深入到共享內存。然后回到了onTransact方法。該方法里調用了我們的具體實現(xiàn)類的對應方法。這里指的BinderManager(不要被名字迷惑,因為這個aidl恰好是管理本地不同aidl生成不同binder的。所以這么叫的一個類)。

另外,這里Stub跟他的代理。因為他們都實現(xiàn)了同一個接口,此處是IBinderManager。所以代理。

另外,剛才說的是子進程到主進程的通信。那么主進程如何通知子進程呢,也是通過AIDL。因為在子進程中我們已經(jīng)拿到了主進程的Binder。所以,在這個binder的方法里,可以聲明一個方法,把我們的aidl生成的類作為一個參數(shù)傳過去,那這樣主進程就拿到了子進程的binder。就可以隨時回調了。

參考

徹底理解Android Binder通信架構
Android:學習AIDL,這一篇文章就夠了(上)
android web模塊獨立進程的實現(xiàn)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容