用户登录
用户注册

分享至

Android利用Binder实现进程通信

  • 作者: 糖宝宝ing
  • 来源: 51数据库
  • 2021-07-12

跨进程通信方式有很多,本文仅针对利用Binder实现。

创建服务端

  • 写一个service类继承service,在onbind方法中返回自己的BInder,在MyBinder的onTransact方法中接受客户端发来的消息,并发送消息到客户端。客户端的消息通过data,readString()方法获取,服务端发送消息通过reply,writerString()方法发送

注意:reply.writeNoException()这个方法,服务端如果写了这个方法,客户端获取服务端消息也必须要写reply.readException()这个方法。必须成对出现,否则获取不到服务端的消息

    public IBinder onBind(Intent intent) {
        MyBinder binder=new MyBinder();

        return binder;
    }
    class MyBinder extends Binder{
        @Override
        protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {
            if (code == 1) {
                String s = data.readString();
                Log.i("ReviceService", "客户端发来的消息是 " + s);
                reply.writeNoException();
                reply.writeString("我是服务端发来的消息");
                return true;

            }
            return super.onTransact(code, data, reply, flags);
        }
    }
  • 在AndroidManifest文件中注册服务,并开启多进程,多进程通过process属性指定,带:号为私有进程
<service android:name=".ReviceService" android:process=":reviceservice">

            <intent-filter>
                <action android:name="android.intent.action.reviceService"></action>
            </intent-filter>
        </service>

创建客户端

  • 写一个类实现ServiceConnection接口,在onServiceConnected方法中与服务端交互。

? ?可以看到onTransact有四个参数?

  • code?是一个整形的唯一标识,用于区分执行哪个方法,客户端会传递此参数,告诉服务端执行哪个方法;
  • data客户端传递过来的参数;
  • replay服务器返回回去的值;
  • flags标明是否有返回值,0为有(双向),1为没有(单向)。

注意transact()直到服务端的Binder.onTransact()方法调用完成后才返回,所以想获取服务端发送的消息必须在onTransact()方法后获取。否则获取不到服务端发来的消息。

class  MessServiceConnect implements ServiceConnection{
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        Parcel data=Parcel.obtain();
        data.writeString("我是客户端发过来的消息");
        Parcel reply=Parcel.obtain();
        try {
            service.transact(1,data,reply,0);
            reply.readException();
            String s = reply.readString();
            Log.i(TAG, "服务端发来的消息: "+s);
        } catch (RemoteException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

    }

绑定服务

  • 用隐式意图绑定服务时注意必须要设置包名,否则会报错
Intent intent=new Intent("android.intent.action.reviceService");
        intent.setPackage("com.afscope.video");
        MessServiceConnect conn = new MessServiceConnect();
        bindService(intent, conn,BIND_AUTO_CREATE);

?

软件
前端设计
程序设计
Java相关