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

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                #AIDL --- 1. 創建一個接口,再里面定義方法 ``` package com.example.taidl; interface ICalcAIDL { int add(int x , int y); int min(int x , int y ); } ``` build一下gen目錄下會生成ICalcAIDL.java文件 ``` /* * This file is auto-generated. DO NOT MODIFY. * Original file: /Users/dream/Downloads/android/androidProject/TAIDL/src/com/example/taidl/ICalcAIDL.aidl */ package com.example.taidl; public interface ICalcAIDL extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.example.taidl.ICalcAIDL { private static final java.lang.String DESCRIPTOR = "com.example.taidl.ICalcAIDL"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.example.taidl.ICalcAIDL interface, * generating a proxy if needed. */ public static com.example.taidl.ICalcAIDL asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof com.example.taidl.ICalcAIDL))) { return ((com.example.taidl.ICalcAIDL)iin); } return new com.example.taidl.ICalcAIDL.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_add: { data.enforceInterface(DESCRIPTOR); int _arg0; _arg0 = data.readInt(); int _arg1; _arg1 = data.readInt(); int _result = this.add(_arg0, _arg1); reply.writeNoException(); reply.writeInt(_result); return true; } case TRANSACTION_min: { data.enforceInterface(DESCRIPTOR); int _arg0; _arg0 = data.readInt(); int _arg1; _arg1 = data.readInt(); int _result = this.min(_arg0, _arg1); reply.writeNoException(); reply.writeInt(_result); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements com.example.taidl.ICalcAIDL { 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; } @Override public int add(int x, int y) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(x); _data.writeInt(y); mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0); _reply.readException(); _result = _reply.readInt(); } finally { _reply.recycle(); _data.recycle(); } return _result; } @Override public int min(int x, int y) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(x); _data.writeInt(y); mRemote.transact(Stub.TRANSACTION_min, _data, _reply, 0); _reply.readException(); _result = _reply.readInt(); } finally { _reply.recycle(); _data.recycle(); } return _result; } } static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_min = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); } public int add(int x, int y) throws android.os.RemoteException; public int min(int x, int y) throws android.os.RemoteException; } ``` 2. 新建一個Service ``` package com.example.taidl; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; public class CalcService extends Service{ private static final String TAG = "server"; public void onCreate() { Log.e(TAG, "onCreate"); } public IBinder onBind(Intent t) { Log.e(TAG, "onBind"); return mBinder; } public void onDestroy() { Log.e(TAG, "onDestroy"); super.onDestroy(); } public boolean onUnbind(Intent intent) { Log.e(TAG, "onUnbind"); return super.onUnbind(intent); } public void onRebind(Intent intent) { Log.e(TAG, "onRebind"); super.onRebind(intent); } private final ICalcAIDL.Stub mBinder = new ICalcAIDL.Stub() { @Override public int min(int x, int y) throws RemoteException { return x + y; } @Override public int add(int x, int y) throws RemoteException { // TODO Auto-generated method stub return x - y; } }; } ``` 創建了一個mBinder對象,并在Service的onBind方法中返回 注冊: ``` <service android:name="com.example.taidl.CalcService"> <intent-filter> <action android:name="com.example.taidl.calc" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </service> ``` 我們一會會在別的應用程序中通過Intent來查找此Service;這個不需要Activity,所以我也就沒寫Activity,安裝完成也看不到安裝圖標,悄悄在后臺運行著。服務端編寫完畢。下面開始編寫客戶端: ``` package com.example.tclient; import com.example.taidl.ICalcAIDL; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.view.View; import android.widget.Toast; public class MainActivity extends Activity { private ICalcAIDL mCalcAidl; private ServiceConnection mServiceConn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { Log.e("client", "onServiceDisconnected"); mCalcAidl = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.e("client", "onServiceConnected"); mCalcAidl = ICalcAIDL.Stub.asInterface(service); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } /** * 點擊BindService按鈕時調用 * @param view */ public void bindService(View view) { Intent intent = new Intent(); intent.setAction("com.example.taidl.calc"); bindService(intent, mServiceConn, Context.BIND_AUTO_CREATE); } /** * 點擊unBindService按鈕時調用 * @param view */ public void unbindService(View view) { unbindService(mServiceConn); } /** * 點擊12+12按鈕時調用 * @param view */ public void addInvoked(View view) throws Exception { if (mCalcAidl != null) { int addRes = mCalcAidl.add(12, 12); Toast.makeText(this, addRes + "", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "服務器被異常殺死,請重新綁定服務端", Toast.LENGTH_SHORT) .show(); } } /** * 點擊50-12按鈕時調用 * @param view */ public void minInvoked(View view) throws Exception { if (mCalcAidl != null) { int addRes = mCalcAidl.min(50, 12); Toast.makeText(this, addRes + "", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "服務器未綁定或被異常殺死,請重新綁定服務端", Toast.LENGTH_SHORT) .show(); } } } ``` 將服務端的aidl文件完整的復制過來,包名一定要一致。 ##分析AIDL生成的代碼 1. 服務端 ``` private final ICalcAIDL.Stub mBinder = new ICalcAIDL.Stub() { @Override public int add(int x, int y) throws RemoteException { return x + y; } @Override public int min(int x, int y) throws RemoteException { return x - y; } }; ``` ICalcAILD.Stub來執行的,讓我們來看看Stub這個類的聲明: ``` public static abstract class Stub extends android.os.Binder implements com.zhy.calc.aidl.ICalcAIDL ``` 清楚的看到這個類是Binder的子類,是不是符合我們文章開通所說的服務端其實是一個Binder類的實例 接下來看它的onTransact()方法: ``` @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_add: { data.enforceInterface(DESCRIPTOR); int _arg0; _arg0 = data.readInt(); int _arg1; _arg1 = data.readInt(); int _result = this.add(_arg0, _arg1); reply.writeNoException(); reply.writeInt(_result); return true; } case TRANSACTION_min: { data.enforceInterface(DESCRIPTOR); int _arg0; _arg0 = data.readInt(); int _arg1; _arg1 = data.readInt(); int _result = this.min(_arg0, _arg1); reply.writeNoException(); reply.writeInt(_result); return true; } } return super.onTransact(code, data, reply, flags); } ``` 文章開頭也說到服務端的Binder實例會根據客戶端依靠Binder驅動發來的消息,執行onTransact方法,然后由其參數決定執行服務端的代碼。 可以看到onTransact有四個參數 code , data ,replay , flags * code 是一個整形的唯一標識,用于區分執行哪個方法,客戶端會傳遞此參數,告訴服務端執行哪個方法 * data客戶端傳遞過來的參數 * replay服務器返回回去的值 * flags標明是否有返回值,0為有(雙向),1為沒有(單向) 我們仔細看case TRANSACTION_min中的代碼 data.enforceInterface(DESCRIPTOR); 與客戶端的writeInterfaceToken對用,標識遠程服務的名稱 ``` int _arg0; _arg0 = data.readInt(); int _arg1; _arg1 = data.readInt(); ``` 接下來分別讀取了客戶端傳入的兩個參數 ``` int _result = this.min(_arg0, _arg1); reply.writeNoException(); reply.writeInt(_result); ``` 然后執行this.min,即我們實現的min方法;返回result由reply寫回。 add同理,可以看到服務端通過AIDL生成Stub的類,封裝了服務端本來需要寫的代碼。 ###客戶端 客戶端主要通過ServiceConnected與服務端連接 ``` private ServiceConnection mServiceConn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { Log.e("client", "onServiceDisconnected"); mCalcAidl = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.e("client", "onServiceConnected"); mCalcAidl = ICalcAIDL.Stub.asInterface(service); } }; ``` 如果你比較敏銳,應該會猜到這個onServiceConnected中的IBinder實例,其實就是我們文章開通所說的Binder驅動,也是一個Binder實例 在ICalcAIDL.Stub.asInterface中最終調用了: ``` return new com.zhy.calc.aidl.ICalcAIDL.Stub.Proxy(obj); ``` 這個Proxy實例傳入了我們的Binder驅動,并且封裝了我們調用服務端的代碼,文章開頭說,客戶端會通過Binder驅動的transact()方法調用服務端代碼 直接看Proxy中的add方法 ``` @Override public int add(int x, int y) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(x); _data.writeInt(y); mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0); _reply.readException(); _result = _reply.readInt(); } finally { _reply.recycle(); _data.recycle(); } return _result; } ``` 首先聲明兩個Parcel對象,一個用于傳遞數據,一個用戶接收返回的數據 ``` _data.writeInterfaceToken(DESCRIPTOR);與服務器端的enforceInterfac對應 _data.writeInt(x); _data.writeInt(y);寫入需要傳遞的參數 mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0); ``` 終于看到了我們的transact方法,第一個對應服務端的code,_data,_repay分別對應服務端的data,reply,0表示是雙向的 ``` _reply.readException(); _result = _reply.readInt(); ``` 最后讀出我們服務端返回的數據,然后return。可以看到和服務端的onTransact基本是一行一行對應的。 我們已經通過AIDL生成的代碼解釋了Android Binder框架的工作原理。Service的作用其實就是為我們創建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>

                              哎呀哎呀视频在线观看