Binder总结-使用篇

Binder不用多说,Android的核心机制之一,用于进程间通信,更加安全,只进行一次拷贝数据。

1.创建aidl文件

package com.example.davidzhaodz.myapplication;

// Declare any non-default types here with import statements

interface IMyAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
    void add(int a, int b);  //这个是你要使用的函数
}

2.创建service,这里面实现了add。IMyAidlInterface.Stub是as编译aidl文件自动生成的

public class TestService extends Service {

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mIBinder;
    }

    private final IBinder mIBinder = new IMyAidlInterface.Stub() {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        @Override
        public void add(int a, int b) throws RemoteException {
            Log.e("david", "test add - remote");
        }
    };

}

3.关于自动生成的IMyAidlInterface.java

主要有两个内部类Stub和Proxy,其实这两个类是真正用于binder通信的。多说两句,其实client对server的访问时分两种的,一种是在同一个进程,这时候binder直接通信,不需要代理。第二种是,在不同的进程,这时server端的是binder的代理,是真的要通过binder驱动进行跨进程通信了

public static com.example.davidzhaodz.myapplication.IMyAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.example.davidzhaodz.myapplication.IMyAidlInterface))) {
return ((com.example.davidzhaodz.myapplication.IMyAidlInterface)iin);//本地接口
}
return new com.example.davidzhaodz.myapplication.IMyAidlInterface.Stub.Proxy(obj);//返回代理
}

其实这里些播放器用aidl。有人说是大炮打蚊子,其实只是看起来大炮打蚊子,实际逻辑并不是这样,因为有这样的逻辑判断

4.在你的activity里bindservice,调用函数。别忘了service添加到manifest

private void testService() {
    Log.e("david", "testService");
    Intent intent = new Intent(this, TestService.class);
    bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);

}

private IMyAidlInterface mIMyAidlInterface;
private ServiceConnection mServiceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
        try {
            mIMyAidlInterface.add(3, 4);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

    }
};

一个基本的binder调用就基本完成了

题外话:

1.service为什么有onBind,想了想,其实service就是通过binder来进行通信的,可以跨进程,可以是同一个进程

2.不用aidl怎么实现。看一下IMyAidlInterface.java,就知道了。最主要的Stub,就是继承了Binder,实现了接口。如果自己来写,也只要继承Binder,实现接口,同时注意需要实现onTransact,是最重要的。这里有个重要区别,本地Binder是onTranscat,而代理调用Trancat,也就是说onTrancat是在服务端的(返回数据),Trancat是在客户端(发送数据)。看代码理解。

3.从framework来说,应用调用系统服务,wms/ams/ims都是跨进程调用,因为这些系统服务是属于systemserver的.同样看源码可以知道,这些系统服务都是按照binder调用来写的,而且为了便于app调用,framework有时把client端的接口实现也写好了,所以有时我们调用起来,感觉不到binder

网上有个不错的例子 https://github.com/yuanhuihui/BinderSample 他把app/framework/native都谢了例子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值