美文网首页
Service通信以及跨进程通信

Service通信以及跨进程通信

作者: mercuryli | 来源:发表于2018-07-28 15:48 被阅读0次

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里面的东西.

@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如图下所示是可以发送对此消息的答复。也就是一个可以返回消息的信使。

client 端新建activity并且在onServiceConnected方法中获得该messenger。

备注:service必须设置属性能够被其他应用程序组件调用或跟它交互。以及要设置匹配项,如上图就是用action 和package调用的service.

现在我们看请求方法也就是由messenger发送一个带有replyTo的消息 这个消息将会发送到sevice中又service的SHandler 处理。而SHandler 中又能获取的Client端的reMessenger通过reMessenger发送消息又能将消息发送到Cilent的Handler从而达到通信。简单来说就是c/s相互给对方传递了自己的messenger从而达到通信。

3.aidl方式跨进程通信

在service端新建一个AIDL Folder  ,New ->Floder ->AIDL Folder.

在该目录下新建一个aidl,新建的一个aidl方法会自动生成一个方法,该方法是用来告诉我们可以传输的数据类型,我们将该方法删除新建一个自己想要的方法。这里我写了一个getNotice方法。现在写好了之后我们编译一下。

编译后在如下目录下会出现一个interface

打开该文件,我们可以看到我们自己定义的方法外还有一个stub,而在messenger的构造方法中也出现了。

里面有一个DESCRIPTOR用来标记该interface的asInterface()方法可以从系统中获取到标记的stub代理类。也就是提供给客户端调用的。

然后我们需要写一个service

然后我们把这个aidl文件复制到client端。注意哦包名要和service端一致。

然后我们就可以在client的activity里头搞事情了。和上面一样serviceconnction加bindservice q调用service.在onServiceConnected方法里面拿到该interface。

拿到它之后我们就可以用它来调用之前我们写的方法啦

aidl虽然理解起来有点复杂,但是对于调用者来说还是很方便的。

github链接

相关文章

网友评论

      本文标题:Service通信以及跨进程通信

      本文链接:https://www.haomeiwen.com/subject/oxapmftx.html