让人纠结的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>