zoukankan      html  css  js  c++  java
  • Android binder介绍(下)

    上一篇: <Android binder介绍(上)>

    5. Java Binder

    Android中也实现了Java层的binder接口

    主要代码如下

    /framework/base/core/java/android/os/
        - IInterface.java
        - IBinder.java
        - Parcel.java
        - IServiceManager.java
        - ServiceManager.java
        - ServiceManagerNative.java
        - Binder.java
    
    /framework/base/core/jni/
        - android_os_Parcel.cpp
        - AndroidRuntime.cpp
        - android_util_Binder.cpp

    5.1 基础类

    /*
     * package android.os;
     * 
     */
    IInterface         - Binder接口基类
    IBinder            - 远程对象接口基类
    IServiceManager    - ServiceManager代理接口, 继承自IInterface
    
    Binder             - 本地Binder, 继承自IBinder, 对应native层的BnBinder
    BinderProxy        - 远程Binder, 继承自IBinder, 对应native层的BpBinder

    class_ServiceManager

    5.2 ServiceManager

    ServiceManager类是servicemanager在Jave层代理, 对应native层的IServiceManager

    public final class ServiceManager {
        private static IServiceManager getIServiceManager() {
        }
    
        public static IBinder getService(String name) {
        }
    
        public static void addService(String name, IBinder service) {
        }
    
        public static IBinder checkService(String name) {
        }
    
        public static String[] listServices() {
        }
    
        public static void initServiceCache(Map<String, IBinder> cache) {
        }
    }
    
    ServiceManager::getIServiceManager()
        /*
         * 实际是Binder.allowBlocking(BinderInternal.getContextObject())
         * 获取ServiceManagerProxy(BinderProxy)
         */
        IBinder binder = BinderInternal.getContextObject()
            // JNI method in android_util_Binder.cpp
            android_os_BinderInternal_getContextObject()
                // Get a native BpBinder
                ProcessState::self()
                    new ProcessState("/dev/binder")
                        open_driver("/dev/binder")
                        mmap()
                ProcessState::getContextObject(NULL)
                    getStrongProxyForHandle(0)
                        BpBinder::create(NULL)
                            new BpBinder(NULL, uid)
                // Transform the native BpBinder to BinderProxy
                javaObjectForIBinder(, new BpBinder())
        /*
         * 将Binder对象转化为IServiceManager对象
         */
        ServiceManagerNative.asInterface(binder)
            // 这里似乎没有使用
            binder.queryLocalInterface("android.os.IServiceManager")
            // 这是实际的返回值
            new ServiceManagerProxy(binder)
    
    ServiceManager::getService(name)
        ServiceManager::rawGetService(name)
            ServiceManager::getIServiceManager().getService(name)
                ServiceManagerProxy::getService(name)
                BinderProxy::transact(GET_SERVICE_TRANSACTION, , , )
                // JNI method in android_util_Binder.cpp
                android_os_BinderProxy_transact(GET_SERVICE_TRANSACTION)
                    BpBinder::transact(GET_SERVICE_TRANSACTION)
                    IPCThreadState::transact(GET_SERVICE_TRANSACTION)
                        IPCThreadState::waitForResponse()
                            IPCThreadState::talkWithDriver()
                                ioctl(binder_fd, BINDER_WRITE_READ, )
    
    ServiceManager::addService(name, )
        ServiceManager::getIServiceManager().addService(name, )
            ServiceManagerProxy::addService(name, )
                BinderProxy::transact(ADD_SERVICE_TRANSACTION, , , )
                ...

    5.3 实例

    这里介绍以下在Java framework层实现server和client的方法,以IFixMe为例

    接口实现

    // IFixMe.java
    package com.test.binder;
    
    import android.os.IInterface;
    import android.os.RemoteException;
    
    public interface IFixMe extends android.os.IInterface {
        static final int TRANSACTION_FUNC = android.os.IBinder.FIRST_CALL_TRANSACTION;
        static final java.lang.String DESCRIPTOR = "com.test.binder.IFixMe";
        public void func(String str) throws RemoteException ;
    }

    Server实现

    // FixMe.java
    package com.test.binder;
    
    import android.os.Binder;
    import android.os.IBinder;
    import android.os.Parcel;
    import android.os.RemoteException;
    
    public class FixMe extends android.os.Binder implements IFixMe{ 
        public FixMe() {
            this.attachInterface(this, DESCRIPTOR);
        }
    
        @Override
        public IBinder asBinder() {
            return this;
        }
    
        public static com.test.binder.IFixMe asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iInterface = obj.queryLocalInterface(DESCRIPTOR);
            if (((iInterface != null) && (iInterface instanceof com.test.binder.IFixMe))) {
                return ((com.test.binder.IFixMe)iInterface);
            }
            return null;
        }
    
        @Override
        protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
                throws RemoteException {
            switch (code) {
            case INTERFACE_TRANSACTION: {
                reply.writeString(DESCRIPTOR);
                return true;
            }
            case TRANSACTION_FUNC: {
                data.enforceInterface(DESCRIPTOR);
                String str = data.readString();
                func1(str);
                reply.writeNoException();
                return true;
            }
            }
            return super.onTransact(code, data, reply, flags);
        }
    
        @Override
        public void func(String str) {
            // Do something...
        }
    }

    Proxy实现

    // FixMeProxy.java
    package com.test.binder;
    
    import android.os.IBinder;
    import android.os.RemoteException;
    
    public class FixMeProxy implements IFixMe {
        private android.os.IBinder mRemote;
    
        public FixMeProxy(android.os.IBinder remote) {
            mRemote = remote;
        }
    
        public java.lang.String getInterfaceDescriptor() {
            return DESCRIPTOR;
        }
    
        @Override
        public void func(String str) throws RemoteException {
            android.os.Parcel _data = android.os.Parcel.obtain();
            android.os.Parcel _reply = android.os.Parcel.obtain();
            try {
                _data.writeInterfaceToken(DESCRIPTOR);
                _data.writeString(str);
                mRemote.transact(TRANSACTION_FUNC, _data, _reply, 0);
                _reply.readException();
            } finally {
                _reply.recycle();
                _data.recycle();
            }
        }
    
        @Override
        public IBinder asBinder() {
            return mRemote;
        }
    }

    测试程序

    package com.test.binder;
    
    import android.os.Looper;
    import android.os.ServiceManager;
    import android.os.RemoteException;
    
    // server test demo
    public class ServerDemo {
        public static void main(String[] args) {
            Looper.prepareMainLooper();
            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
            ServiceManager.addService("FixMe", newFixMe());
            Looper.loop();
        }
    }
    
    // client test demo
    public class ClientDemo {
        public static void main(String[] args) throws RemoteException {
            IBinder binder = ServiceManager.getService("FixMe");
            IFixMe myService = newFixMeProxy(binder);
            myService.func("binder");
        }
    }

    其他实例可参考 <BinderSample>

    6. AIDL

    从前面看出编写一个Java/C++层面的binder通信比较复杂,在Android中为了简化这种操作提出了AIDL的概念,简单来说就是按照一定的规则编写AIDL接口让编译器来自动生成Proxy和Server端相关代码

    下面分别介绍一下Java和C++使用AIDL的实例

    6.1 Java AIDL

    AIDL接口

    // IFixMe.aidl
    package com.test.binder;
    
    interface IFixMe {
        int func(String msg);
    }

    可以使用android build-tools中的aidl工具将其转化为java代码

    $ aidl.exe com/test/binder/IFixMe.aidl
    
    // IFixMe.java内容如下
    interface IFixMe
        func()
        // Server端
        class Stub
            asInterface
            asBinder
            onTransact
        // Proxy端
        class Proxy
            asBinder
            getInterfaceDescriptor
            func

    Server实现

    import com.test.binder;
    
    public class FixMeService extends IFixMe.Stub {
        @Override
        public int func() throws android.os.RemoteException {
            // Do something
            return 0;
        }
    }

    测试程序

    package com.test.binder;
    
    import android.os.Looper;
    import android.os.ServiceManager;
    import android.os.RemoteException;
    
    // server test demo
    public class ServerDemo {
        public static void main(String[] args) {
            Looper.prepareMainLooper();
            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
            ServiceManager.addService("FixMe", new FixMeService());
            Looper.loop();
        }
    }
    
    // client test demo
    public class ClientDemo {
        public static void main(String[] args) throws RemoteException {
            IBinder binder = ServiceManager.getService("FixMe");
            IFixMe myService = IHelloService.Stub.asInterface(binder);
            myService.func("binder");
        }
    }

    TIP:值得一说的是ServiceManager相关接口只能在framework中使用,在app端使用aidl需要和Service一起使用

    Java AIDL使用方法参考<AIDLDemo>

    6.2 C++ AIDL

    AIDL接口

    // IFixMe.aidl
    package com.test.binder;
    
    interface IFixMe {
        int func(String msg);
    }

    使用android build-tools中的aidl-cpp工具将其转化为C++代码

    $ aidl-cpp com/test/binder/IFixMe.aidl . com/test/binder/FixMe.cpp
    
    在com/test/binder/生成如下文件
    IFixMe.h
        class IFixMe : public android::IInterface
            DECLARE_META_INTERFACE(FixMe)
            func()
    BnFixMe.h
        class BnFixMe : public android::BnInterface<IFixMe>
            onTransact()
    BpFixMe.h
        class BpFixMe : public android::BpInterface<IFixMe>
            func()
    FixMe.cpp
        // 实现如下方法
        BnFixMe::onTransact()
        BpFixMe::func()

    Server实现

    // FixMeService.h
    class FixMeService : public os::BnFixMe {
    public:
        int func(String msg);
    }
    
    // FixMeService.cpp
    int FixMeService::func(String msg) {
        // Do something
        return 0;
    }

    测试程序这里不再累述,值得一说是的native层面封装了BinderService来简化添加服务的操作

    可参考NetdNativeService(system/netd)和VoldNativeService(system/vold)

    7. HIDL

    这里就不详叙了,以后有需要再添加

    参考:
    <Binder系列>
    <Android HIDL>
    <AIDL的基本使用>
    <HAL接口定义语言(HIDL)>
    <Android接口定义语言(AIDL)>

  • 相关阅读:
    [Delphi]ListView基本用法大全
    Delphi 数据类型列表
    什么是堆、栈?
    使用钩子函数[1]
    邻道干扰
    内存管理[1]
    c#中复制类提示“Resource”参数不支持重复项的解决办法
    转帖:IE对话框showModalDialog(模态)和showModelessDialog
    今日工作心得:一段用于验证的jQuery代码
    每个开发人员现在应该下载的十种必备工具
  • 原文地址:https://www.cnblogs.com/hzl6255/p/12117227.html
Copyright © 2011-2022 走看看