Android studio 使用aidl和service进行进程间通信

一.概述
Android的Binder机制可以进行进程间通信,但是Servicemanager这个类不公开,也就是我在自己的应用程序中无法使用Servicemanager的addService将我们自己定义的service注册到binder中去,也无法通过getService获取到对应的Service,那么在我们的应用程序要如何来进行进程间通信呢?利用aidl文件和Service就可以进行通信了.
二.编写AIDL文件
这里写图片描述
在android studio按如上方法就可以创建aidl文件,在aidl文件中定义相关的功能,比如我在这里就定义了一个getString 方法:
这里写图片描述
将编写好的aidl文件编译就会生成同名的.java文件.为什么生成的aidl文件可以进行进程间通信呢,因为它会自动帮我们生成对应的Binder子类stub和对应的proxy类,至于这2个类是做什么的,这就涉及到了binder的知识,binder知识不是一下可以说清楚的,只能靠自己去研究了.
三.编写Service

public class WatchDogService extends Service {


    public IBinder onBind(Intent intent) {

        return new MyBind();
    }

    @Override
    public void onDestroy() {


        super.onDestroy();
    }

    @Override
    public void onCreate() {

        super.onCreate();


    }
    //这个类就是继承自aidl编译后生成的对应的.java件中的Stub类,它是Binder的子类
    class MyBind extends test.Stub{

        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        /**重写 getString 方法
        @Override
        public String getString(String str) throws RemoteException {
            return "远程服务返回的数据:"+str;
        }
    }
}

四.将servie注册到AndroidManifest.xml中

 <service android:name="com.betterda.test3.actiivty.WatchDogService">
            <intent-filter>
                <action android:name="com.lypeer.aidl"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>

        </service>

五.在另外一个应用程序中绑定servie
上面的service就定义在com.betterda.test3这个包名的应用程序中,接下来我在com.betterda.test2这个包名的应用程序中通过bindService来启动WatchDogService,然后调用test接口中定义的getString方法可以获取到WatchDogService返回的信息了,下面的代码就是bindservice

 Intent intent = new Intent();
        intent.setAction("com.lypeer.aidl");
        intent.setPackage("com.betterda.test3");
        if (!isBind) {
            //因为是在另外一个程序的servie,所以只能通过action和package来绑定servie
            bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
        }

  private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {

            isBind = true;
            //绑定成功以后,会返回在Service的onbind方法中返回的binder对象,我们在WatchDogService的onbind方法中返回就是new MyBind(),它是test.Stub类
            //所以我们在这里可以得到Stub的Proxy对象
            mTest = test.Stub.asInterface(service);

            try {
                //通过proxy的代理对象就可以调用getstring方法
                String string = mTest.getString("你好");
                Toast.makeText(MainActivity.this, string,0).show();
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            isBind = false;
            Log.e(getLocalClassName(), "service disconnected");

        }
    };

在上面的代码中我们将绑定servive返回binder转换来test.Stub的Proxy对象,然后才能调用在test接口中定义的方法,所以在这个com.betterda.test2应用程序也要定义一个同样功能的aidl文件,这个只要将com.betterda.test3中定义的aidl文件拷贝过来,然后重新编译就会自定生成了,运行com.betterda.test2就可以看到getString返回:远程服务返回的数据:你好

六.总结
想要在进程间通信使用都是Binder机制,aidl和bindService就为了方便开发者在自己的应用程序中使用Binder机制来通信,bindService就是代替了ServiceManager的addService来向Binder驱动注册服务.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值