让人纠结的AIDL进程间通信,原本想把里面的机制都看懂,但是看了许久还是晕晕的,感觉里面封装的太多,所以就先了解一下AIDL的简单运用好了。
这里我写了一个调用Service中的两个方法的Demo,以下是效果图:
下面是代码:
新建Activity,E_AIDLActivity.java
package com.wly.E_AIDL; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; import android.widget.Toast; public class E_AIDLActivity extends Activity { Button bindService,unbindService,usePlusMethod,useMinusMethod; private Methods methods; private ServiceConnection conn = new ServiceConnection() { //将在绑定解除后调用 @Override public void onServiceDisconnected(ComponentName name) { } //将在绑定建立后调用,注意此方法的第二个参数是一个IBinder接口对象, //是一个通信信道,我认为这个参数就是E_AIDLActivity中onBind方法的返回对象 @Override public void onServiceConnected(ComponentName name, IBinder service) { methods = Methods.Stub.asInterface(service); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //为了减少布局文件的考虑,采用从代码创建布局 bindService = new Button(this); unbindService = new Button(this); usePlusMethod = new Button(this); useMinusMethod = new Button(this); bindService.setText("bindService"); unbindService.setText("unbindService"); useMinusMethod.setText("useMinusMethod"); usePlusMethod.setText("usePlusMethod"); LinearLayout linearLayout = new LinearLayout(this); linearLayout.setOrientation(LinearLayout.VERTICAL); linearLayout.addView(bindService); linearLayout.addView(usePlusMethod); linearLayout.addView(useMinusMethod); linearLayout.addView(unbindService); useMinusMethod.setEnabled(false); usePlusMethod.setEnabled(false); unbindService.setEnabled(false); setContentView(linearLayout); //绑定到服务 bindService.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setAction("com.wly.E_AIDLService"); //注意此处的action数据,是E_AIDLService中的action数据 usePlusMethod.setEnabled(true); useMinusMethod.setEnabled(true); unbindService.setEnabled(true); bindService(intent, conn, BIND_AUTO_CREATE); //绑定服务 Toast.makeText(E_AIDLActivity.this, "绑定已建立", 1).show(); } }); //使用代理对象调用E_AIDLService服务中的plus方法 usePlusMethod.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { Toast.makeText(E_AIDLActivity.this, "34" + " + 12 = " + methods.plus(34, 12), 1).show(); } catch (RemoteException e) { e.printStackTrace(); } } }); //使用代理对象调用E_AIDLService服务中的minus方法 useMinusMethod.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { Toast.makeText(E_AIDLActivity.this, "34" + " - 12 = " + methods.minus(34, 12), 1).show(); } catch (RemoteException e) { e.printStackTrace(); } } }); //解除绑定 unbindService.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { unbindService(conn); bindService.setEnabled(true); usePlusMethod.setEnabled(false); useMinusMethod.setEnabled(false); unbindService.setEnabled(false); Toast.makeText(E_AIDLActivity.this, "绑定已解除!", 1).show(); } }); } }
新建一个dial接口文件Methods.aidl,其中主要实现了两个方法(plus,minus)
package com.wly.E_AIDL; interface Methods{ int plus(int a,int b); int minus(int a,int b); }
新建服务端(service),其中主要是初始化了一个stub代理对象,我认为该代理对象在客户端的onServiceConnected方法引用,用来初始化客户端的代理对象(E_AIDLActivity中的methods对象)
package com.wly.E_AIDL; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; public class E_AIDLService extends Service { //实现在aidl文件中声明的方法,其实是将这些实现的方法通过aidl文件生成的对象向外暴露 Methods.Stub methods = new Methods.Stub() { @Override public int plus(int a, int b) throws RemoteException { return a + b; } @Override public int minus(int a, int b) throws RemoteException { return a - b; } }; @Override public IBinder onBind(Intent intent) { return methods; //调用methods对象,并将其返回给客户端(即本Demo中的E_AIDLActivity) } @Override public void onDestroy() { super.onDestroy(); } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } }
下面是清单文件,注意service元素声明时的action属性是自定义的,且在客户端中用来定义启动service的Intent
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.wly.E_AIDL" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="7" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".E_AIDLActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".E_AIDLService"> <intent-filter > <action android:name="com.wly.E_AIDLService"></action> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </service> </application> </manifest>