欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android开发指南之Binder源码分析

程序员文章站 2022-03-27 21:26:38
Android开发指南之Binder源码分析。 AIDL中的Binder实现 在 Android AIDL实现进程间通信中,我们曾提到要想实现IPC,我们需要通过定义.aidl...

Android开发指南之Binder源码分析。

AIDL中的Binder实现

在 Android AIDL实现进程间通信中,我们曾提到要想实现IPC,我们需要通过定义.aidl接口来实现。其实,创建.aidl文件的目的就是让SDK为为我们自动生成.aidl文件对应的java类,该类的主要核心就是Binder。

现在我们就主要对SDK系统生成的Java类进行分析一下。

这里是定义的IContactsService.aidl。

// IContactsService.aidl
package com.zhangke.aidlserverdemo;

// Declare any non-default types here with import statements
import com.zhangke.aidlserverdemo.Contacts;

interface IContactsService {
    /**
    *保存联系人
    */
    int saveContacts(in Contacts contacts);
    /**
     *获取联系人列表
     */
    List getContactsList();
}

下面是SDK自动生成的IContactsService.java类,该类继承自android.os.IInterface接口。

这里有几个主要的属性和方法:

DESCTIPTOR:Binder的唯一标识 asInterface():返回客户端需要的AIDL接口类型的对象 asBinder():IInterface接口定义的方法,返回Binder对象 onTransact():IPC的核心方法,也是RPC(远程过程调用)的流程 Proxy#saveContacts和Proxy#getContactsList:AIDL接口定义的方法,该方法也是提供给客户端调用的方法。
/**
 * SDK生成的java类, 该类继承自android.os.IInterface接口
 */
public interface IContactsService extends android.os.IInterface {
    /**
     * 该类继承自Binder,并且实现了IContactsService接口,这里有方法的具体实现
     */
    public static abstract class Stub extends android.os.Binder implements com.zhangke.aidlserverdemo.IContactsService {
        private static final java.lang.String DESCRIPTOR = "com.zhangke.aidlserverdemo.IContactsService";

        /**
         * 在服务中,一般都是通过创建该类,然后获取对应Binder引用
         */
        public Stub() {
            /**
             * 将IContactsService接口和Binder关联起来
             */
            this.attachInterface(this, DESCRIPTOR);
        }

        /**
         * 将Binder对象转换成与之对应的IContactsService接口对象,
         * IContactsService对象一般会在客户端被使用
         */
        public static com.zhangke.aidlserverdemo.IContactsService asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            /**
             * obj.queryLocalInterface(DESCRIPTOR),该方法判断客户端和服务器是否是在同一进程,如果是同一个进程,则返回服务对象本身
             * 否则,会返回系统封装的Proxy对象
             */
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof com.zhangke.aidlserverdemo.IContactsService))) {
                return ((com.zhangke.aidlserverdemo.IContactsService) iin);
            }
            return new com.zhangke.aidlserverdemo.IContactsService.Stub.Proxy(obj);
        }

        /**
         * 该方法是android.os.IInterface接口中的方法,返回当前Binder对象
         * 一般在绑定服务的onBind()方法中,通过该方法返回Binder对象
         */
        @Override
        public android.os.IBinder asBinder() {
            return this;
        }

        /**
         * 核心方法
         * 

* 1、该方法运行在服务端的Binder线程池中,当客户端发起请求后,服务端根据code参数确定客户端请求的具体方法 */ @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_saveContacts: { data.enforceInterface(DESCRIPTOR); com.zhangke.aidlserverdemo.Contacts _arg0; if ((0 != data.readInt())) { /** * 2、通过data参数,获取客户端输入的参数 */ _arg0 = com.zhangke.aidlserverdemo.Contacts.CREATOR.createFromParcel(data); } else { _arg0 = null; } /** * 3、执行目标方法 */ int _result = this.saveContacts(_arg0); reply.writeNoException(); /** * 4、写入返回值 */ reply.writeInt(_result); /** * 该返回值如果返回false,说明请求调用会失败 */ return true; } case TRANSACTION_getContactsList: { data.enforceInterface(DESCRIPTOR); java.util.List _result = this.getContactsList(); reply.writeNoException(); reply.writeTypedList(_result); return true; } } return super.onTransact(code, data, reply, flags); } /** * Stub的内部类,在客户端和服务端不是同一个进程时会使用 */ private static class Proxy implements com.zhangke.aidlserverdemo.IContactsService { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } @Override public int saveContacts(com.zhangke.aidlserverdemo.Contacts contacts) throws android.os.RemoteException { // 1、 创建输入参数和输出参数 android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); if ((contacts != null)) { // 2、写入输入型参数 _data.writeInt(1); contacts.writeToParcel(_data, 0); } else { _data.writeInt(0); } /* * 3、调用RPC请求,该过程会导致客户端线程挂起,然后服务端的onTransact()方法会被调用, * 直到RPC完成,客户端线程继续执行 */ mRemote.transact(Stub.TRANSACTION_saveContacts, _data, _reply, 0); _reply.readException(); // 4、获取RPC的返回结果,最终返回到客户端 _result = _reply.readInt(); } finally { _reply.recycle(); _data.recycle(); } return _result; } /** * 获取联系人列表 */ @Override public java.util.List getContactsList() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); java.util.List _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getContactsList, _data, _reply, 0); _reply.readException(); _result = _reply.createTypedArrayList(com.zhangke.aidlserverdemo.Contacts.CREATOR); } finally { _reply.recycle(); _data.recycle(); } return _result; } } /** * 系统生成参数,用于确定请求方法 */ static final int TRANSACTION_saveContacts = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_getContactsList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); } /** * 保存联系人 * * @param contacts * @return * @throws android.os.RemoteException */ public int saveContacts(com.zhangke.aidlserverdemo.Contacts contacts) throws android.os.RemoteException; /** * 获取联系人列表 */ public java.util.List getContactsList() throws android.os.RemoteException; }

IInterface源码分析

package android.os;

/**
 * Binder接口的基类,要想实现Binder必须实现该接口
 */
public interface IInterface
{
    /**
     * 查找与接口对应的Binder对象,必须通过该方法才能使Proxy      * 对象返回一个正确的结果
     */
    public IBinder asBinder();
}