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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                經過上一節的介紹,讀者已經明白在Java層Binder的架構中,Bp端可以通過BinderProxy的transact()方法與Bn端發送請求,而Bn端通過繼承Binder類并重寫onTransact()接收并處理來自Bp端的請求。這個結構非常清晰而且簡單,但是實現起來卻頗為繁瑣。于是Android提供了AIDL語言以及AIDL解釋器自動生成一個服務的Bn端即Bp端的用于處理Binder通信的代碼。 AIDL的語法與定義一個Java接口的語法非常相似。為了避免業務實現對分析的干擾,本節通過一個最簡單的例子對AIDL的原理進行介紹: **IMyServer.aidl** ``` package com.understanding.samples; interface IMyServer { intfoo(String str); } ``` IMyServer.aidl定義了一個名為IMyServer的Binder服務,并提供了一個可以跨Binder調用的接口foo()。可以通過aidl工具將其解析為一個實現了Bn端及Bp端通過Binder進行通信的Java源代碼。具體命令如下: ``` aidl com/understanding/samples/IMyServer.aidl ``` 生成的IMyServer.java可以在com/understanding/samples/文件夾下找到。 * * * * * **建議** 讀者可以閱讀aidl有關的文檔了解此工具的詳細功能。 * * * * * **IMyServer.java-->IMyServer** ``` package com.understanding.samples; /* **① 首先,IMyServer.aidl被解析為一個Java接口IMyServer。**這個接口定義了AIDL文件中 所定義的接口foo() */ public interface IMyServer extendsandroid.os.IInterface { /***② aidl工具生成了一個繼承自IMyServer接口的抽象類IMyServer.Stub。**這個抽象類實現了 Bn端通過onTransact()方法接收來自Bp端的請求的代碼。本例中的foo()方法在這個類中 會被定義成一個抽象方法。因為aidl工具根不知道foo()方法是做什么的,它只能在onTransact() 中得知Bp端希望對foo()方法進行調用,所以Stub類是抽象的。 */ publicstatic abstract class Stub extends android.os.Binder implements com.understanding.samples.IMyServer{ ...... // Stub類的其他實現 /*onTransact()根據code的值選擇調用IMyServer接口中的不同方法。本例中 TRANSACTION_foo意味著需要通過調用foo()方法完成請求 */ public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { ...... case TRANSACTION_foo: { ...... // 從data中讀取參數_arg0 // Stub類的子類需要實現foo()方法 int _result = this.foo(_arg0); ...... // 向reply中寫入_result return true; } } return super.onTransact(code, data, reply, flags); } /* **③ aidl工具還生成了一個繼承自IMyServer接口的類Proxy,它是Bp端的實現。**與Bn端的 Stub類不同,它實現了foo()函數。因為foo()函數在Bp端的實現是確定的,即將參數存儲到 Parcel中然后執行transact()方法將請求發送給Bn端,然后從reply中讀取返回值并返回 給調用者 */ private static class Proxy implements com.understanding.samples.IMyServer{ ...... // Proxy類的其他實現 public int foo(java.lang.String str) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); int _result; try { ...... // 將參數str寫入參數_data // mRemote就是指向IMyServer Bn端的BinderProxy mRemote.transact(Stub.TRANSACTION_foo, _data, _reply, 0); ......// 從_replay中讀取返回值_result } finally { ...... } return _result; } } // TRANSACTION_foo常量用于定義foo()方法的code static final int TRANSACTION_foo = (android.os.IBinder.FIRST_CALL_TRANSACTION+ 0); } // 聲明IMyServer所提供的接口 publicint foo(java.lang.String str) throws android.os.RemoteException; } ``` 可見一個AIDL文件被aidl工具解析之后會產生三個物件: - IMyServer接口。它僅僅用來在Java中聲明IMyServer.aidl中所聲明的接口。 - IMyServer.Stub類。這個繼承自Binder類的抽象類實現了Bn端與Binder通信相關的代碼。 - IMyServer.Stub.Proxy類。這個類實現了Bp端與Binder通信相關的代碼。 在完成了aidl的解析之后,為了實現一個Bn端,開發者需要繼承IMyServer.Stub類并實現其抽象方法。如下所示: ``` class MyServer extends IMyServer.Stub { intfoo(String str) { // 做點什么都可以 returnstr.length(); } } ``` 于是每一個MyServer類的實例,都具有了作為Bn端的能力。典型的做法是將MyServer類的實例通過ServiceManager.addService()將其注冊為一個系統服務,或者在一個Android標準Service的onBind()方法中將其作為返回值使之可以被其他進程訪問。另外,也可以通過Binder調用將其傳遞給另外一個進程,使之成為一個跨進程的回調對象。 那么Bp端將如何使用IMyServer.Proxy呢?在Bp端所在進程中,一旦獲取了IMyServer的BinderProxy(通過ServiceManager.getService()、onServiceConnected()或者其他方式),就可以以如下方式獲得一個IMyServer.Proxy: ``` // 其中binderProxy就是通過ServiceManager.getService()所獲取 IMyServer remote = IMyServer.Stub.asInterface(binderProxy); remote.foo(“Hello AIDL!”); IMyServer.Stub.asInterface()的實現如下: [IMyServer.java-->IMyServer.Stub.asInterface()] public static com.understanding.samples.IMyServerasInterface( android.os.IBinder obj) { ...... // 創建一個IMyServer.Stub.Proxy。其中參數obj將會被保存為Proxy類的mRemote成員。 return new com.understanding.samples.IMyServer.Stub.Proxy(obj); } ``` 可見,AIDL使得構建一個Binder服務的工作大大地簡化了。
                  <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>

                              哎呀哎呀视频在线观看