1.service和activiy通信
要求:activity 要调用service的方法
首先我们写一个service,重写onbind方法,在该方法中需要返回一个IBinder,所以我们本地写一个继承binder的TBinder ,在TBinder 中写一个方法将TService返出去这也就是我们待会要用activiy获取service的方式。
public class TService extends Service{
private IBinder binder = new TBinder();
@Nullable
@Override
public IBinder onBind(Intent intent){
return binder;
}
class TBinder extends Binder{
TService getService(){
return TService.this;
}
}
private Random util = new Random();
public int getNumber (){
return util.nextInt(100);
}
}
在activity中写一个serviceconnection,。通过bindservice方法启动service,在serviceconnect的时候用如下方式获取到binder即可获取到service。这样就可以调用service中的方法了。
connection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
TService.TBinder binder = (TService.TBinder) service;
services = binder.getService();
Log.e("servcice","onServiceConnected");
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e("servcice","onServiceDisconnected");
}
};
Intent intent =new Intent(this,TService.class);
bindService(intent,connection,BIND_AUTO_CREATE);
2.跨进程service通信
新建两个项目一个作为服务端,另一个作为客户端。我们将通过messenger+handler的方式来通信。如下所示,在service里写一个handler,再新建一个Messenger ,在onBind方法中返回Messenger的IBinder。先不管handler里面的东西.
![](https://img.haomeiwen.com/i10515939/483649bd0dc3c483.png)
@Nullable
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
Messenger messenger = new Messenger(new SHandler());
class SHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
Messenger reMessenger = msg.replyTo;
Message message = Message.obtain(null,1);
Bundle b = new Bundle();
b.putInt("number",getNumber());
message.setData(b);
try {
reMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
default:
super.handleMessage(msg);
}
}
}
先看看replyTo,Message 的replayTo也是一个messenger如图下所示是可以发送对此消息的答复。也就是一个可以返回消息的信使。
![](https://img.haomeiwen.com/i10515939/9800fe85f7ab47bc.png)
client 端新建activity并且在onServiceConnected方法中获得该messenger。
![](https://img.haomeiwen.com/i10515939/12697ace3315e150.png)
备注:service必须设置属性能够被其他应用程序组件调用或跟它交互。以及要设置匹配项,如上图就是用action 和package调用的service.
现在我们看请求方法也就是由messenger发送一个带有replyTo的消息 这个消息将会发送到sevice中又service的SHandler 处理。而SHandler 中又能获取的Client端的reMessenger通过reMessenger发送消息又能将消息发送到Cilent的Handler从而达到通信。简单来说就是c/s相互给对方传递了自己的messenger从而达到通信。
![](https://img.haomeiwen.com/i10515939/030405821d203004.png)
3.aidl方式跨进程通信
在service端新建一个AIDL Folder ,New ->Floder ->AIDL Folder.
![](https://img.haomeiwen.com/i10515939/247d2fa65ab64318.png)
在该目录下新建一个aidl,新建的一个aidl方法会自动生成一个方法,该方法是用来告诉我们可以传输的数据类型,我们将该方法删除新建一个自己想要的方法。这里我写了一个getNotice方法。现在写好了之后我们编译一下。
![](https://img.haomeiwen.com/i10515939/215fe725d20f8ea9.png)
![](https://img.haomeiwen.com/i10515939/a67995ccc2d1d30b.png)
编译后在如下目录下会出现一个interface
![](https://img.haomeiwen.com/i10515939/69873c907497b428.png)
打开该文件,我们可以看到我们自己定义的方法外还有一个stub,而在messenger的构造方法中也出现了。
![](https://img.haomeiwen.com/i10515939/8a29bb08871d6708.png)
![](https://img.haomeiwen.com/i10515939/ee84b9d7ee0183ce.png)
![](https://img.haomeiwen.com/i10515939/86c16e16661edeb1.png)
里面有一个DESCRIPTOR用来标记该interface的asInterface()方法可以从系统中获取到标记的stub代理类。也就是提供给客户端调用的。
然后我们需要写一个service
![](https://img.haomeiwen.com/i10515939/7eb7977d39eb3e69.png)
然后我们把这个aidl文件复制到client端。注意哦包名要和service端一致。
![](https://img.haomeiwen.com/i10515939/39d754e599ca31ac.png)
然后我们就可以在client的activity里头搞事情了。和上面一样serviceconnction加bindservice q调用service.在onServiceConnected方法里面拿到该interface。
![](https://img.haomeiwen.com/i10515939/de10d7d2b05bb871.png)
拿到它之后我们就可以用它来调用之前我们写的方法啦
![](https://img.haomeiwen.com/i10515939/0d138198c020d22e.png)
aidl虽然理解起来有点复杂,但是对于调用者来说还是很方便的。
网友评论