AIDL的使用步驟
aidl遠程調用傳遞的參數和返回值支持Java的基本類型(int long booen char byte等)和String,List,Map等。當然也支持一個自定義對象的傳遞。
服務端
新建一個MyAidlDemoServer工程,然后在java目錄下右鍵新建一個aidl File,然后在該目錄下新建一個IMyAidlInterface.aidl文件,代碼如下:
修改生成的.aidl文件中的內容
1 interface IMyAidlInterface { 2 3 int add(int arg1, int arg2); 4 5 } //aidl文件里面的代碼不需要加任何修飾符
這里定義了一個IMyAidlInterface接口,里面定義的add方法用於求和計算。
然后Build當前工程(Build選項里的Make Project)。
會發現在app/build/generated/source/aidl/debug目錄下會生成一個與IMyAidlInterface.aidl文件同樣包名的一個文件,該文件下面自動生成IMyAidlInterface文件,該文件里面自動實現了一些方法用於遠程調用。
編寫遠程服務
新建MyService類繼承Service,並實現以下代碼。
1 public class MyService extends Service { 2 IMyAidlInterface.Stub mStub = new IMyAidlInterface.Stub() { 3 @Override 4 public int add(int arg1, int arg2) throws RemoteException { 5 return arg1 + arg2; 6 } 7 }; 8 9 @Override 10 public IBinder onBind(Intent intent) { 11 return mStub; 12 } 13 }
服務里的代碼重寫了IMyAidlInterface.Stub類中的 add方法,然后通過重寫onBind()方法將重寫的IMyAidlInterface.Stub類返回出去。
然后在AndroidManifest.xml對Service進行配置。
1 <service 2 android:process=":remote" 3 android:name=".MyService" 4 android:enabled="true" 5 android:exported="true"> 6 <intent-filter> 7 <action android:name="co.example.leo.myService"/> 8 </intent-filter> 9 </service>
這里設置了android:process屬性,並且設置為":remote"。
android:process=":remote",代表在應用程序里,當需要該service時,會自動創建新的進程。而如果是android:process="remote",沒有“:”分號的,則創建全局進程,不同的應用程序共享該進程。
然后添加了一個意圖過濾器。
客戶端
新建MyAidlDemoCustomer工程,然后直接把服務端的aidl目錄直接拷貝到客戶端的main目錄下。這么一來客戶端的aidl就無需編寫了,直接和服務端的一模一樣。包括路徑的包名等。 當然也可以在客戶端這邊重新寫aidl文件。
編輯布局文件:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent"> 5 6 <TextView 7 android:id="@+id/tv" 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content" 10 android:textSize="30sp" /> 11 </LinearLayout>
這里只用了一個TextView來顯示最終的計算結果。
然后編輯客戶端的調用代碼:
1 public class MainActivity extends AppCompatActivity { 2 3 TextView tv; 4 IMyAidlInterface mStub; 5 6 @Override 7 protected void onCreate(Bundle savedInstanceState) { 8 super.onCreate(savedInstanceState); 9 setContentView(R.layout.activity_main); 10 11 tv = (TextView)findViewById(R.id.tv); 12 13 Intent intent = new Intent(); 14 //由於是隱式啟動Service 所以要添加對應的action,A和之前服務端的一樣。 15 intent.setAction("co.example.leo.myService"); 16 //android 5.0以后直設置action不能啟動相應的服務,需要設置packageName或者Component。 17 intent.setPackage("co.example.leo.myaidldemoserver"); //packageName 需要和服務端的一致. 18 bindService(intent,serviceConnection,BIND_AUTO_CREATE); 19 } 20 21 private ServiceConnection serviceConnection = new ServiceConnection() { 22 @Override 23 public void onServiceConnected(ComponentName name, IBinder service) { 24 //調用asInterface()方法獲得IMyAidlInterface實例 25 mStub = IMyAidlInterface.Stub.asInterface(service); 26 if (mStub == null) { 27 Log.e("MainActivity", "the mStub is null"); 28 } else { //當mStub不為空就調用其add方法進行計算,並顯示到TextView上面。 29 try { 30 int value = mStub.add(1, 8); 31 tv.setText(value + ""); 32 } catch (RemoteException e) { 33 e.printStackTrace(); 34 } 35 } 36 } 37 38 @Override 39 public void onServiceDisconnected(ComponentName name) { 40 41 } 42 }; 43 44 45 @Override 46 protected void onDestroy(){ 47 //解綁服務 48 super.onDestroy(); 49 unbindService(serviceConnection); 50 } 51 }
最后安裝上客戶端和服務端,打開客戶端后會發現已經調用了服務端的方法並計算出了結果。
總結
這是一個在AS下最簡單的一個AIDL編程:
1.服務端創建一個aidl目錄,然后在該目錄下新建一個.aidl為后綴的接口類,該類定義遠程調用的接口方法。
2.build編譯之后會在app/build/generated/source/aidl/debug目錄下會生成aidl遠程實現類,該類是AS自動生成的。
3.在AndroidManifest.xml下配置Service的action和process屬性。
4.將服務端的aidl目錄拷貝到客戶端相應的目錄下,然后編寫客戶端調用代碼,AS下簡單的aidl編程就ok了。