在工作中会有Android中使用AIDL 绑定Service通信,使用起来也是停留在会用。
读了任玉刚的书《android开发艺术探索》后也是一知半解,还是做一个Demo来对着书分析一下吧。
这篇先做一个AIDL通信Demo,备忘一下搬运过程。
1)建立两个Module,一个是客户端App,一个是服务端serverapp
同时在俩个Module中建立两个AIDL文件夹,并且建立aidl文件如下
package com.xue.qin.aidl;
interface IMyAidlInterface {
String getCurrentTime(int which);
}
这里的包名和aidl文件的名字和aidl文件的内容要保证完全一致。
这个Aidl文件会在如下图的位置生成一个java文件,具体的等下一篇继续分析。
(甚至可以吧aidl文件删掉,把这个java文件可以拷贝到通aidl文件相同包中使用)
2)服务端开启服务,在serverapp中建立一个Service对外提供服务manifest中注册此服务。
<service android:name=".ServerService">
<intent-filter>
<action android:name="remoteService"></action>
</intent-filter>
</service>
在server中建立放回的BInder,具体的下篇继续分析。
private class MyBinder extends IMyAidlInterface.Stub{
@Override
public String getCurrentTime(int which) throws RemoteException {
String result="";
switch (which){
case 0:
SimpleDateFormat sdf = new SimpleDateFormat("", Locale.SIMPLIFIED_CHINESE);
sdf.applyPattern("yyyy年MM月dd日 \nHH时mm分ss秒");
result = sdf.format(System.currentTimeMillis());
break;
case 1:
result = "开机之后过去了\n "+formatTime(SystemClock.elapsedRealtime());
break;
case 2:
//SystemClock.uptimeMillis() 去掉休眠的时间
result = "实际使用了\n" +formatTime(SystemClock.uptimeMillis());
break;
}
return result;
}
}
自定义个MyBinder 继承自IMyAidlInterface的内部类stub(就是第一步自动生成的那个java文件),重写接口getCurrentTime()方法,以提供给客户端调用。
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
重写onBind()并且返回一个MyBinder()
3)客户端绑定服务,app要访问这个服务端就要先与其建立绑定。
Intent intent = new Intent("remoteService");
intent.setPackage("com.xue.qin.server");
boolean success = bindService(intent, mConntection, Context.BIND_AUTO_CREATE);
因为不是在同一个进程里,intent要设置服务端的包名才行,然后调用bindService这个函数,参数分别
Intent:请求Intent
ServiceConnection:绑定状态回调
flags:启动的方式 Context.BIND_AUTO_CREATEb表示如果Service没有启动那么就创建并启动它。
返回值 如果绑定成功返回true 失败返回false
第三个参数需要新建一个ServiceConnection接口如下:
private ServiceConnection mConntection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "onServiceConnected()");
mService = IMyAidlInterface.Stub.asInterface(service);
mHandler.post(mRunable);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "onServiceDisconnected()");
mService = null;
}
};
这里当绑定成功时onServiceConnected()会被回调,
a、这里的IBinder service 这个参数service就是在服务端返回的Mybinder;
声明这个Aidl接口来接受这个返回值,其中IMyAidlInterface mService;
mService = IMyAidlInterface.Stub.asInterface(service);
b、当绑定断开时onServiceDisconnected()会被回调。
拿到这个返回的接口之后,就可以在客户端调用服务端的回调了。
mService.getCurrentTime(mCount%3)
最后使用,要先安装服务端,然后就可以把服务端退掉了。
再安装客户端运行效果如下。
demo地址 https://github.com/xueqin123/repository1