<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                #### binder的工作機制 下面的代碼是在IBookManager.aidl中,系統自動生成的IBookManager.java文件 ~~~ /* * This file is auto-generated. DO NOT MODIFY. */ package com.ryg.chapter_2; /* * IBookManager它繼承了IInterface這個接口,同時它自己也還是個接口, * 所有可以在Binder中傳輸的接口都要繼承IInterface接口。 * * 首先,它聲明了兩個方法getBookList和addBook(在最后面),顯然這就是我們在IBookManager.aidl中所聲明的方法, * 同時它還聲明了兩個整型的id(TRANSACTION_getBookList、TRANSACTION_addBook)分別用于標識這兩個方法。 * 接著,它聲明了一個內部類Stub,這個Stub就是一個Binder類, * 當客戶端和服務端都位于同一個進程時,方法調用不會走跨進程的transact過程, * 而當兩者位于不同進程時,方法調用需要走transact過程, * 這個邏輯由Stub的內部代理類Proxy來完成。 * *這個接口的核心就是內部類Stub和Stub的內部代理類Proxy * */ public interface IBookManager extends android.os.IInterface { /** * Local-side IPC implementation stub class. */ /* * 首先這個Stub,它是一個內部類,它繼承了Binder,所以它是一個Binder, * 同時Stub還實現了IBookManager中的方法。 * */ public static abstract class Stub extends android.os.Binder implements com.ryg.chapter_2.aidl.IBookManager { //Binder的唯一標識符。 一般用于當前Binder的類名表示 private static final java.lang.String DESCRIPTOR = "com.ryg.chapter_2.aidl.IBookManager"; /** * Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface (this, DESCRIPTOR); } /** * Cast an IBinder object into an com.ryg.chapter_2.aidl.IBookManager interface, * generating a proxy if needed. */ /* * 用于將服務端的Binder對象轉換成客戶端所需的AIDL接口類型的對象, * 這種轉換過程是區分進程的, * 如果客戶端和服務端位于同一進程,那么此方法返回的就是服務端的Stub對象本身, * 否則(即客戶端和服務端不在同一個進程)返回的是系統封裝后的Stub.proxy代理對象。 * */ public static com.ryg.chapter_2.aidl.IBookManager asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface (DESCRIPTOR); // 同一進程 if (((iin != null) && (iin instanceof com.ryg.chapter_2.aidl.IBookManager))) { return ((com.ryg.chapter_2.aidl.IBookManager) iin); } // 不同進程 return new com.ryg.chapter_2.aidl.IBookManager.Stub.Proxy (obj); } //此方法用于返回當前Binder對象,也就是內部類Stub。 @Override public android.os.IBinder asBinder() { return this; } /* * 這個方法運行在服務端中的Binder線程池中, * 當客戶端發起跨進程請求時,遠程請求會通過系統底層封裝后交由此方法來處理。 * 該方法的原型是 public Boolean onTransact(int code,android.os.Parcel data,android.os.Parcel reply,int flags) * 服務端通過code可以確定客戶端所請求的目標方法是什么, * 接著從data中取出目標方法所需的參數, * 然后執行目標方法。 * 當目標方法執行完畢后,就向reply中寫入返回值。 * 如果此方法返回false,那么客戶端的請求會失敗,因此我們可以利用這個特性來做權限驗證。 * (畢竟也不希望隨便一個進程都可以遠程調用我們的服務) * */ @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_getBookList: { data.enforceInterface (DESCRIPTOR); //這句才是調用了真正的執行過程呢 java.util.List<com.ryg.chapter_2.aidl.Book> _result = this.getBookList (); reply.writeNoException (); reply.writeTypedList (_result); return true;//返回true表示調用成功 } case TRANSACTION_addBook: { data.enforceInterface (DESCRIPTOR); com.ryg.chapter_2.aidl.Book _arg0; if ((0 != data.readInt ())) { _arg0 = com.ryg.chapter_2.aidl.Book.CREATOR.createFromParcel (data); } else { _arg0 = null; } //這句才是調用了真正的執行過程呢 this.addBook (_arg0); reply.writeNoException (); return true; } case TRANSACTION_registerListener: { data.enforceInterface (DESCRIPTOR); com.ryg.chapter_2.aidl.IOnNewBookArrivedListener _arg0; _arg0 = com.ryg.chapter_2.aidl.IOnNewBookArrivedListener.Stub.asInterface (data.readStrongBinder ()); this.registerListener (_arg0); reply.writeNoException (); return true; } case TRANSACTION_unregisterListener: { data.enforceInterface (DESCRIPTOR); com.ryg.chapter_2.aidl.IOnNewBookArrivedListener _arg0; _arg0 = com.ryg.chapter_2.aidl.IOnNewBookArrivedListener.Stub.asInterface (data.readStrongBinder ()); this.unregisterListener (_arg0); reply.writeNoException (); return true; } } return super.onTransact (code, data, reply, flags); } //代理類Proxy。 private static class Proxy implements com.ryg.chapter_2.aidl.IBookManager { /* * 這個mRemote代表的就是目標對象角色, * */ private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } /* * 這個方法運行在客戶端, * 因為當客戶端和服務端不在同一進程時,服務端返回代理類Proxy,所以客戶端會通過Proxy調用到代理類的getBookList方法, * 當客戶端遠程調用此方法時,它的內部實現是這樣的: * 首先創建該方法所需要的輸入型Parcel對象_data、輸出型Parcel對象_reply和返回值對象List, * 然后把該方法的參數信息寫入_data中, * 接著調用transact方法來發起RPC(遠程過程調用)請求,同時當前線程掛起, * 然后服務端的onTransact方法會被調用,直到RPC過程返回后,當前線程繼續執行, * 并從_reply中取出RPC過程的返回結果。 * 最后返回_reply中的數據。 * */ @Override public java.util.List<com.ryg.chapter_2.aidl.Book> getBookList() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain (); android.os.Parcel _reply = android.os.Parcel.obtain (); java.util.List<com.ryg.chapter_2.aidl.Book> _result; try { _data.writeInterfaceToken (DESCRIPTOR); mRemote.transact (Stub.TRANSACTION_getBookList, _data, _reply, 0); _reply.readException (); _result = _reply.createTypedArrayList (com.ryg.chapter_2.aidl.Book.CREATOR); } finally { _reply.recycle (); _data.recycle (); } return _result; } /** * 這個方法運行在客戶端,執行過程和getBookList一樣,只是addBook沒有返回值, * 所以不需要從_reply中取出返回值 */ @Override public void addBook(com.ryg.chapter_2.aidl.Book book) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain (); android.os.Parcel _reply = android.os.Parcel.obtain (); try { _data.writeInterfaceToken (DESCRIPTOR); if ((book != null)) { _data.writeInt (1); book.writeToParcel (_data, 0); } else { _data.writeInt (0); } mRemote.transact (Stub.TRANSACTION_addBook, _data, _reply, 0); _reply.readException (); } finally { _reply.recycle (); _data.recycle (); } } @Override public void registerListener(com.ryg.chapter_2.aidl.IOnNewBookArrivedListener listener) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain (); android.os.Parcel _reply = android.os.Parcel.obtain (); try { _data.writeInterfaceToken (DESCRIPTOR); _data.writeStrongBinder ((((listener != null)) ? (listener.asBinder ()) : (null))); mRemote.transact (Stub.TRANSACTION_registerListener, _data, _reply, 0); _reply.readException (); } finally { _reply.recycle (); _data.recycle (); } } @Override public void unregisterListener(com.ryg.chapter_2.aidl.IOnNewBookArrivedListener listener) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain (); android.os.Parcel _reply = android.os.Parcel.obtain (); try { _data.writeInterfaceToken (DESCRIPTOR); _data.writeStrongBinder ((((listener != null)) ? (listener.asBinder ()) : (null))); mRemote.transact (Stub.TRANSACTION_unregisterListener, _data, _reply, 0); _reply.readException (); } finally { _reply.recycle (); _data.recycle (); } } } /* * 用于標識方法的整型id。 * 它們用于在transact過程總客戶端所請求的到底是哪個方法。 * */ static final int TRANSACTION_getBookList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_addBook = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); static final int TRANSACTION_registerListener = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2); static final int TRANSACTION_unregisterListener = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3); } /* * 聲明了在IBookManager.aidl中所聲明的方法。 * 這里才是真正的方法聲明。具體實現我們仍然沒有看到呢。 * */ public java.util.List<com.ryg.chapter_2.aidl.Book> getBookList() throws android.os.RemoteException; public void addBook(com.ryg.chapter_2.aidl.Book book) throws android.os.RemoteException; public void registerListener(com.ryg.chapter_2.aidl.IOnNewBookArrivedListener listener) throws android.os.RemoteException; public void unregisterListener(com.ryg.chapter_2.aidl.IOnNewBookArrivedListener listener) throws android.os.RemoteException; } ~~~ ![](https://box.kancloud.cn/2016-05-29_574aa689ca354.png) 對于上圖有網友這樣理解,原文點擊[這里](http://blog.csdn.net/zizidemenghanxiao/article/details/50341773) 對于自動生成的IBookManager.java文件,它是服務器端的代碼。 當客戶端向服務端發送連接請求時, * 如果客戶端和服務端在同一進程中,那么服務端就向客戶端返回Stub這個Binder對象, * 如果客戶端和服務端在不同進程中,那么服務端就向客戶端返回內部類Stub的內部代理類Proxy,然后客戶端根據這個Proxy來調用Proxy內部的方法,這個Proxy內部含有服務端真正的Binder對象也就是那個內部類Stub,在客戶端調用Proxy內部的方法也就會導致調用Stub的transact方法,而Stub的transact方法又會回調它自己的onTransact方法,onTransact方法是在服務端運行的,而transact方法是在客戶端調用的,這樣就實現了客戶端調用服務端的方法了。當然這所有的傳遞過程也少不了Parcel這個數據包的協助。 * * * * * > **Binder一個很重要的作用是:將客戶端的請求參數通過Parcel包裝后傳到遠程服務端,遠程服務端解析數據并執行對應的操作,同時客戶端線程掛起,當服務端方法執行完畢后,再將返回結果寫入到另外一個Parcel中并將其通過Binder傳回到客戶端,客戶端接收到返回數據的Parcel后,Binder會解析數據包中的內容并將原始結果返回給客戶端,至此,整個Binder的工作過程就完成了。由此可見,Binder更像一個數據通道,Parcel對象就在這個通道中跨進程傳輸,至于雙方如何通信,這并不負責,只需要雙方按照約定好的規范去打包和解包數據即可。** * * * * *
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看