简介
AIDL(AndRoid接口描述语言)是一种借口描述语言; 编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程的目的. 如果需要在一个Activity中, 访问另一个Service中的某个对象, 需要先将对象转化成AIDL可识别的参数(可能是多个参数), 然后使用AIDL来传递这些参数, 在消息的接收端, 使用这些参数组装成自己需要的对象.
AIDL 支持的类型
- 简单Java编程语言类型(int,boolean等)
- List
List中的所有元素都必须是可支持的类型中的一个,包括其他AIDL生成接口和parcelables。List可以作为泛型类来灵活使用(比如List<String>)。而实际的接受方的类则总是ArrayList,尽管该方法将被生成来使用List接口。
- Map
Map中的所有元素都必须是可支持的类型中的一个,包括其他AIDL生成接口和parcelables。泛型化的Maps(比如:Map<Stirng,Integer>)不被支持。而实际的接受方的类则总是HashMap,尽管该方法将被生成去使用Map接口。
- CharSequence
CharSequence的作用是可以被TextView和其他Widget对象使用。
使用
服务端
例如目前编写的 PushService
在 SRC 目录中添加文件IPushService.aidl
interface IPushService {
boolean startPushServer(String action);
boolean stopPushServer(String action);
}
Eclipse 会自动生成 java 文件,放在目录 gen/ 包名 /IPushService.java
制作 Service 文件,来实现 IPushService 接口。
public class PushService extends Service {
private IPushService.Stub mBind;
private static final String TAG = "PushService";
@Override
public IBinder onBind(Intent intent) {
return mBind;
}
@Override
public void onCreate() {
Log.d(TAG, "service onCrate.......");
iniBind();
}
private void iniBind(){
mBind = new IPushService.Stub() {
@Override
public boolean stopPushServer(String action) throws RemoteException {
Log.d(TAG, "stopPushServer:"+action);
return false;
}
@Override
public boolean startPushServer(String action) throws RemoteException {
Log.d(TAG, "startPushServer:"+action);
return false;
}
};
}
}
那么一个 AIDL 就建好了,下面讲基本的使用
客户端
首先在新建的项目中添加IPushService.aidl文件,实验证明, IPushService.aidl文件只要定义的内容相同就 OK 了,至于在哪里一个包里都是无所谓的。记得 COPY 过来的时候 ,更改一下 import 的内容。
然后使用如下:
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = new Intent("nd.push.service");
bindService(intent, conn, Context.BIND_AUTO_CREATE);
Button installBtn = (Button) findViewById(R.id.button1);
final ApkEngine engine = new ApkEngine(MainActivity.this);
installBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
engine.install("/sdcard/qq.apk");
}
});
Button serviceBtn = (Button) findViewById(R.id.button2);
serviceBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mPushService != null) {
try {
mPushService
.stopPushServer("test push server close request");
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
});
Button callBtn = (Button) findViewById(R.id.button3);
callBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mPushService != null) {
try {
mPushService
.startPushServer("test push server open request");
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
});
}
private IPushService mPushService;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d("MainActivity", "onServiceDisconnected");
mPushService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("MainActivity", "onServiceConnected");
mPushService = IPushService.Stub.asInterface(service);
}
};
@Override
protected void onStop() {
super.onStop();
unbindService(conn);
}
}
这里要注意的是bindService和unbindService是要成双成对出现的否则将会出现一些错误。