Android O Binder 通讯机制分析--简单使用

Binder通讯其实是android 系统的基础,所有的系统服务基本都是基于Binder通讯的,如果不懂Binder通讯,那么我想你理解android 框架层的代码就很艰难了。

那么到底什么是Binder通讯呢??其实它是一种跨进程通讯机制,有一个服务段,有一个客户端,而且客户端可以跨进程调用服务段的函数,并且获取结果,其实跨进程通讯有很多,比如socket通讯就是,只是比较简单而已。Binder通讯支持调用远程服务端的函数如调用本地函数一样,支持Java 基本数据类型做参数和返回值,并且Binder通讯支持服务端和客户端都是纯C++或者纯java 。这样的设计大大简化了用户设计Binder通讯程序的复杂度,因为google将所有的复杂通讯进制全部隐藏了。

当然,如果只是理解并使用的话,则不需要了解底层的设计,也可以使用,但是在跟其他同事交流的过程中发现,很多同事都是看到binder通讯这里看不懂我设计的代码了。这一度让我很费解,我想你们不需要明白这么多就可以了,但是依然无法阻挡大家的好奇心,或者求知欲,因此我花费时间详细研究了这一块,所以今天把它写出来,供大家参考。

其实在O版本之前android只有Binder通讯,而O版本之后,android将system和vendor分离,将框架和底层适配分离,大大增加了系统的解耦性,而binder通讯也成了框架层通讯的专有东西。所以google重新设计了hidl,hwbinder通讯来用于vendor分区的应用或者服务使用。但是如果你不了解binder机制的话,那么你也不太可能理解hwbinder通讯,因为hwbinder与binder机制类似,是在binder通讯的基础上设计出来的,可以看作一个克隆版本,不过同样的,你一样可以使用hwbinder通讯,因为使用是简单的,而细节是复杂的,并且被深深的隐藏在幕后。


 

Binder 通讯基本框图

Binder通讯简单的使用则包含一个client 和service 端,service 端包含BnXXXBinder 服务,这个BnXXXBinder 服务其实就是封装的通讯细节。所有的服务实现都在XXXService 内,但是其他服务如何才能调用呢??这些就是BnXXXbinder和BpXXXBinder 的作用了。BpXXXBinder 被客户端使用,他会将所有IXXXService 服务提供的接口,都封装成访问远程通讯并等待结果的形式,而BnXXXBinder 服务接收并调用服务端的接口然后把函数的结果重新打包发送给BpXXXBinder 。

现在我使用一个我以前设计的程序来讲解其原理:

package com.factory.ata;
import com.factory.ata.IAtaMsgEvent;
interface IAtaFactoryService{
    void registerClient(String pkg,IAtaMsgEvent msgReady);
    void unregisterClient(String pkg);
    String metaCtr(String msg);
}

这个就是一个aidl接口的服务,aidl文件如上所示。

如果你写的是一个java层的服务的话,那么你只要编译这个文件,则自动生产如下java接口:

/*___Generated_by_IDEA___*/

/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: /Users/haozhenghui/Documents/闻泰/mmigroup_miui/wt_apps/FactoryAPP/FactoryInterface/factoryInterface/src/com/factory/ata/IAtaFactoryService.aidl
 */
package com.factory.ata;

public interface IAtaFactoryService extends android.os.IInterface {
    /**
     * Local-side IPC implementation stub class.
     */
    public static abstract class Stub extends android.os.Binder implements com.factory.ata.IAtaFactoryService {
        private static final java.lang.String DESCRIPTOR = "com.factory.ata.IAtaFactoryService";

        /**
         * Construct the stub at attach it to the interface.
         */
        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

        /**
         * Cast an IBinder object into an com.factory.ata.IAtaFactoryService interface,
         * generating a proxy if needed.
         */
        public static com.factory.ata.IAtaFactoryService asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof com.factory.ata.IAtaFactoryService))) {
                return ((com.factory.ata.IAtaFactoryService) iin);
            }
            return new com.factory.ata.IAtaFactoryService.Stub.Proxy(obj);
        }

        @Override
        public android.os.IBinder asBinder() {
            return this;
        }

        @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_registerClient: {
                    data.enforceInterface(DESCRIPTOR);
                    java.lang.String _arg0;
                    _arg0 = data.readString();
                    com.factory.ata.IAtaMsgEvent _arg1;
                    _arg1 = com.factory.ata.IAtaMsgEvent.Stub.asInterface(data.readStrongBinder());
                    this.registerClient(_arg0, _arg1);
                    reply.writeNoException();
                    return true;
                }
                case TRANSACTION_unregisterClient: {
                    data.enforceInterface(DESCRIPTOR);
                    java.lang.String _arg0;
                    _arg0 = data.readString();
                    this.unregisterClient(_arg0);
                    reply.writeNoException();
                    return true;
                }
                case TRANSACTION_metaCtr: {
                    data.enforceInterface(DESCRIPTOR);
                    java.lang.String _arg0;
                    _arg0 = data.readString();
                    java.lang.String _result = this.metaCtr(_arg0);
                    reply.writeNoException();
                    reply.writeString(_result);
                    return true;
                }
            }
            return super.onTransact(code, data, reply, flags);
        }

        private static class Proxy implements com.factory.ata.IAtaFactoryService {
            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 void registerClient(java.lang.String pkg, com.factory.ata.IAtaMsgEvent msgReady) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeString(pkg);
                    _data.writeStrongBinder((((msgReady != null)) ? (msgReady.asBinder()) : (null)));
                    mRemote.transact(Stub.TRANSACTION_registerClient, _data, _reply, 0);
                    _reply.readException();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }

            @Override
            public void unregisterClient(java.lang.String pkg) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeString(pkg);
                    mRemote.transact(Stub.TRANSACTION_unregisterClient, _data, _reply, 0);
                    _reply.readException();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }

            @Override
            public java.lang.String metaCtr(java.lang.String msg) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                java.lang.String _result;
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeString(msg);
                    mRemote.transact(Stub.TRANSACTION_metaCtr, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readString();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }
        }

        static final int TRANSACTION_registerClient = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        static final int TRANSACTION_unregisterClient = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
        static final int TRANSACTION_metaCtr = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
    }

    public void registerClient(java.lang.String pkg, com.factory.ata.IAtaMsgEvent msgReady) throws android.os.RemoteException;

    public void unregisterClient(java.lang.String pkg) throws android.os.RemoteException;

    public java.lang.String metaCtr(java.lang.String msg) throws android.os.RemoteException;
}

然后你只需要继承里面的接口,并且实现方法,然后将它加入ServiceManager 内,则服务端的实现就OK了。

但是如果你要实现的是C++层的服务,则android提供了一个aidl-cpp 的工具将aidl文件生成c++的头文件和cpp文件,这些文件将接口全部转化成bn,bp文件等,你只需要继承这些类,则可以实现底层服务的创建。

aidl-cpp 转换方法:

aidl-cpp \
-I${factoryInterfaceSrc}/ \
${factoryInterfaceSrc}/com/factory/ata/IAtaFactoryService.aidl \
${root_dir}/factoryAtaService/ \
${root_dir}/factoryAtaService/IAtaFactoryServiceProxy.cpp

-I 为aidl的依赖的目录

第二个为aidl源文件,第三个为生成cpp头文件的目录,第四个为生成的代理文件路径。

其实这个IAtaFactoryServiceProxy.cpp 就是将bn,bp 内的方法的实现。隐藏了通讯的细节。

现在我们来逐步分析它的实现

生成的头文件:

BnAtaFactoryService.h
BpAtaFactoryService.h
IAtaFactoryService.h

生成的cpp:

IAtaFactoryServiceProxy.cpp

我们先来分析IAtaFactoryService.h

#ifndef AIDL_GENERATED_COM_FACTORY_ATA_I_ATA_FACTORY_SERVICE_H_
#define AIDL_GENERATED_COM_FACTORY_ATA_I_ATA_FACTORY_SERVICE_H_

#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <binder/Status.h>
#include <com/factory/ata/IAtaMsgEvent.h>
#include <utils/String16.h>
#include <utils/StrongPointer.h>

namespace com {

namespace factory {

namespace ata {

class IAtaFactoryService : public ::android::IInterface {
public:
DECLARE_META_INTERFACE(AtaFactoryService)
virtual ::android::binder::Status registerClient(const ::android::String16& pkg, const ::android::sp<::com::factory::ata::IAtaMsgEvent>& msgReady) = 0;
virtual ::android::binder::Status unregisterClient(const ::android::String16& pkg) = 0;
virtual ::android::binder::Status metaCtr(const ::android::String16& msg, ::android::String16* _aidl_return) = 0;
enum Call {
  REGISTERCLIENT = ::android::IBinder::FIRST_CALL_TRANSACTION + 0,
  UNREGISTERCLIENT = ::android::IBinder::FIRST_CALL_TRANSACTION + 1,
  METACTR = ::android::IBinder::FIRST_CALL_TRANSACTION + 2,
};
};  // class IAtaFactoryService

}  // namespace ata

}  // namespace factory

}  // namespace com

#endif  // AIDL_GENERATED_COM_FACTORY_ATA_I_ATA_FACTORY_SERVICE_H_

这个文件是一个接口文件,里面的方法都是虚函数,不管是服务端的Bn还是客户端的Bp 都需要继承这个文件,这个文件其实类似于CPP端的aidl 接口文件。eunm Call 这个枚举 定义了各个方法的一个键值,后面的通讯其实就是使用这些键值来表示需要调用的函数。

BnAtaFactoryService.h

#ifndef AIDL_GENERATED_COM_FACTORY_ATA_BN_ATA_FACTORY_SERVICE_H_
#define AIDL_GENERATED_COM_FACTORY_ATA_BN_ATA_FACTORY_SERVICE_H_

#include <binder/IInterface.h>
#include <com/factory/ata/IAtaFactoryService.h>

namespace com {

namespace factory {

namespace ata {

class BnAtaFactoryService : public ::android::BnInterface<IAtaFactoryService> {
public:
::android::status_t onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags = 0) override;
};  // class BnAtaFactoryService

}  // namespace ata

}  // namespace factory

}  // namespace com

#endif  // AIDL_GENERATED_COM_FACTORY_ATA_BN_ATA_FACTORY_SERVICE_H_

服务端的Bn其实只有一个通讯函数,而这个通讯函数会根据eunm Call 内的键值来调用服务端的函数,这部分实现在proxy.cpp 中,请稍后。

BpAtaFactoryService.h

#ifndef AIDL_GENERATED_COM_FACTORY_ATA_BP_ATA_FACTORY_SERVICE_H_
#define AIDL_GENERATED_COM_FACTORY_ATA_BP_ATA_FACTORY_SERVICE_H_

#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <utils/Errors.h>
#include <com/factory/ata/IAtaFactoryService.h>

namespace com {

namespace factory {

namespace ata {

class BpAtaFactoryService : public ::android::BpInterface<IAtaFactoryService> {
public:
explicit BpAtaFactoryService(const ::android::sp<::android::IBinder>& _aidl_impl);
virtual ~BpAtaFactoryService() = default;
::android::binder::Status registerClient(const ::android::String16& pkg, const ::android::sp<::com::factory::ata::IAtaMsgEvent>& msgReady) override;
::android::binder::Status unregisterClient(const ::android::String16& pkg) override;
::android::binder::Status metaCtr(const ::android::String16& msg, ::android::String16* _aidl_return) override;
};  // class BpAtaFactoryService

}  // namespace ata

}  // namespace factory

}  // namespace com

#endif  // AIDL_GENERATED_COM_FACTORY_ATA_BP_ATA_FACTORY_SERVICE_H_

Bp 这个类主要是给客户端使用的。当然他的实现也在proxy.cpp 中。现在我们来看看proxy.cpp 的实现吧!

IAtaFactoryServiceProxy.cpp

#include <com/factory/ata/IAtaFactoryService.h>
#include <com/factory/ata/BpAtaFactoryService.h>

namespace com {

namespace factory {

namespace ata {

IMPLEMENT_META_INTERFACE(AtaFactoryService, "com.factory.ata.IAtaFactoryService");

}  // namespace ata

}  // namespace factory

}  // namespace com
#include <com/factory/ata/BpAtaFactoryService.h>
#include <binder/Parcel.h>

namespace com {

namespace factory {

namespace ata {

BpAtaFactoryService::BpAtaFactoryService(const ::android::sp<::android::IBinder>& _aidl_impl)
    : BpInterface<IAtaFactoryService>(_aidl_impl)
{
}

::android::binder::Status BpAtaFactoryService::registerClient(const ::android::String16& pkg, const ::android::sp<::com::factory::ata::IAtaMsgEvent>& msgReady)
{
    ::android::Parcel _aidl_data;
    ::android::Parcel _aidl_reply;
    ::android::status_t _aidl_ret_status = ::android::OK;
    ::android::binder::Status _aidl_status;
    _aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
    if (((_aidl_ret_status) != (::android::OK))) {
        goto _aidl_error;
    }
    _aidl_ret_status = _aidl_data.writeString16(pkg);
    if (((_aidl_ret_status) != (::android::OK))) {
        goto _aidl_error;
    }
    _aidl_ret_status = _aidl_data.writeStrongBinder(::com::factory::ata::IAtaMsgEvent::asBinder(msgReady));
    if (((_aidl_ret_status) != (::android::OK))) {
        goto _aidl_error;
    }
    _aidl_ret_status = remote()->transact(IAtaFactoryService::REGISTERCLIENT, _aidl_data, &_aidl_reply);
    if (((_aidl_ret_status) != (::android::OK))) {
        goto _aidl_error;
    }
    _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
    if (((_aidl_ret_status) != (::android::OK))) {
        goto _aidl_error;
    }
    if (!_aidl_status.isOk()) {
        return _aidl_status;
    }
_aidl_error:
    _aidl_status.setFromStatusT(_aidl_ret_status);
    return _aidl_status;
}

::android::binder::Status BpAtaFactoryService::unregisterClient(const ::android::String16& pkg)
{
    ::android::Parcel _aidl_data;
    ::android::Parcel _aidl_reply;
    ::android::status_t _aidl_ret_status = ::android::OK;
    ::android::binder::Status _aidl_status;
    _aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
    if (((_aidl_ret_status) != (::android::OK))) {
        goto _aidl_error;
    }
    _aidl_ret_status = _aidl_data.writeString16(pkg);
    if (((_aidl_ret_status) != (::android::OK))) {
        goto _aidl_error;
    }
    _aidl_ret_status = remote()->transact(IAtaFactoryService::UNREGISTERCLIENT, _aidl_data, &_aidl_reply);
    if (((_aidl_ret_status) != (::android::OK))) {
        goto _aidl_error;
    }
    _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
    if (((_aidl_ret_status) != (::android::OK))) {
        goto _aidl_error;
    }
    if (!_aidl_status.isOk()) {
        return _aidl_status;
    }
_aidl_error:
    _aidl_status.setFromStatusT(_aidl_ret_status);
    return _aidl_status;
}

::android::binder::Status BpAtaFactoryService::metaCtr(const ::android::String16& msg, ::android::String16 *_aidl_return)
{
    ::android::Parcel _aidl_data;
    ::android::Parcel _aidl_reply;
    ::android::status_t _aidl_ret_status = ::android::OK;
    ::android::binder::Status _aidl_status;
    _aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
    if (((_aidl_ret_status) != (::android::OK))) {
        goto _aidl_error;
    }
    _aidl_ret_status = _aidl_data.writeString16(msg);
    if (((_aidl_ret_status) != (::android::OK))) {
        goto _aidl_error;
    }
    _aidl_ret_status = remote()->transact(IAtaFactoryService::METACTR, _aidl_data, &_aidl_reply);
    if (((_aidl_ret_status) != (::android::OK))) {
        goto _aidl_error;
    }
    _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
    if (((_aidl_ret_status) != (::android::OK))) {
        goto _aidl_error;
    }
    if (!_aidl_status.isOk()) {
        return _aidl_status;
    }
    _aidl_ret_status = _aidl_reply.readString16(_aidl_return);
    if (((_aidl_ret_status) != (::android::OK))) {
        goto _aidl_error;
    }
_aidl_error:
    _aidl_status.setFromStatusT(_aidl_ret_status);
    return _aidl_status;
}

}  // namespace ata

}  // namespace factory

}  // namespace com
#include <com/factory/ata/BnAtaFactoryService.h>
#include <binder/Parcel.h>

namespace com {

namespace factory {

namespace ata {

::android::status_t BnAtaFactoryService::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel *_aidl_reply, uint32_t _aidl_flags)
{
    ::android::status_t _aidl_ret_status = ::android::OK;
    switch (_aidl_code) {
    case Call::REGISTERCLIENT:
        {
            ::android::String16 in_pkg;
            ::android::sp<::com::factory::ata::IAtaMsgEvent> in_msgReady;
            if (!(_aidl_data.checkInterface(this))) {
                _aidl_ret_status = ::android::BAD_TYPE;
                break;
            }
            _aidl_ret_status = _aidl_data.readString16(&in_pkg);
            if (((_aidl_ret_status) != (::android::OK))) {
                break;
            }
            _aidl_ret_status = _aidl_data.readStrongBinder(&in_msgReady);
            if (((_aidl_ret_status) != (::android::OK))) {
                break;
            }
            ::android::binder::Status _aidl_status(registerClient(in_pkg, in_msgReady));
            _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
            if (((_aidl_ret_status) != (::android::OK))) {
                break;
            }
            if (!_aidl_status.isOk()) {
                break;
            }
        }
        break;
    case Call::UNREGISTERCLIENT:
        {
            ::android::String16 in_pkg;
            if (!(_aidl_data.checkInterface(this))) {
                _aidl_ret_status = ::android::BAD_TYPE;
                break;
            }
            _aidl_ret_status = _aidl_data.readString16(&in_pkg);
            if (((_aidl_ret_status) != (::android::OK))) {
                break;
            }
            ::android::binder::Status _aidl_status(unregisterClient(in_pkg));
            _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
            if (((_aidl_ret_status) != (::android::OK))) {
                break;
            }
            if (!_aidl_status.isOk()) {
                break;
            }
        }
        break;
    case Call::METACTR:
        {
            ::android::String16 in_msg;
            ::android::String16 _aidl_return;
            if (!(_aidl_data.checkInterface(this))) {
                _aidl_ret_status = ::android::BAD_TYPE;
                break;
            }
            _aidl_ret_status = _aidl_data.readString16(&in_msg);
            if (((_aidl_ret_status) != (::android::OK))) {
                break;
            }
            ::android::binder::Status _aidl_status(metaCtr(in_msg, &_aidl_return));
            _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
            if (((_aidl_ret_status) != (::android::OK))) {
                break;
            }
            if (!_aidl_status.isOk()) {
                break;
            }
            _aidl_ret_status = _aidl_reply->writeString16(_aidl_return);
            if (((_aidl_ret_status) != (::android::OK))) {
                break;
            }
        }
        break;
    default:
        {
            _aidl_ret_status = ::android::BBinder::onTransact(_aidl_code, _aidl_data, _aidl_reply, _aidl_flags);
        }
        break;
    }
    if (_aidl_ret_status == ::android::UNEXPECTED_NULL) {
        _aidl_ret_status = ::android::binder::Status::fromExceptionCode(::android::binder::Status::EX_NULL_POINTER).writeToParcel(_aidl_reply);
    }
    return _aidl_ret_status;
}

}  // namespace ata

}  // namespace factory

}  // namespace com

大家仔细看看Bp,Bn 的实现,Bp 负责将函数打包,发送,Bn负责解析,然后调用服务端的函数,并返回返回值。

现在我们来看看服务真正的实现代码吧!

#define ANDROID_AIDL_COMMON_ATA_FACTOY_SERVICE_H

#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <utils/Errors.h>
#include <com/factory/ata/IAtaFactoryService.h>
#include <com/factory/ata/BnAtaFactoryService.h>
#include <com/factory/ata/IAtaMsgEvent.h>
#include <binder/Parcel.h>
#include <utils/String8.h>
#include <utils/String16.h>
#include <utils/Vector.h>
#include <utils/StrongPointer.h>
#include <string>
#include <unordered_map>
#include "common.h"

using namespace android;
using namespace com::factory::ata;
using namespace std;
using android::binder::Status;



class ataFactoryService : public BnAtaFactoryService {
public:
    static  void                instantiate();
    ataFactoryService();
    ~ataFactoryService();
    Status registerClient(const String16 &pkg, const sp<IAtaMsgEvent> &msgReady);
    Status unregisterClient(const String16 &pkg);
    Status metaCtr(const String16 &msg, String16 *_aidl_return);




};

#endif

很抱歉,我只能给大家看看代码的头函数,其实现代码,无法分享。但是我觉得看到头文件就可以了。

instantiate()

void ataFactoryService::instantiate() {

    defaultServiceManager()->addService(
        String16("factory.ataService"), new ataFactoryService());

}

这个函数其实就是将服务添加到serviceManager中,然后其他应用就可以通过serviceManager 来获取服务了。

现在我们来看看这个服务端的main函数:

#include "factoryAtaAidlService.h"
#include "module_comm.h"
#include <utils/String8.h>
#include <utils/String16.h>
#include <utils/StrongPointer.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>

#include <com/factory/ata/IAtaFactoryService.h>
#include <com/factory/ata/BnAtaFactoryService.h>
#include <com/factory/ata/IAtaMsgEvent.h>

using namespace android;
using namespace com::factory::ata;

#ifdef LOG_TAG
#undef LOG_TAG
#define LOG_TAG "factoryServices"
#endif

int main()
{
    MMI_ALOGI("start factoryAtaService");
    sp<android::ProcessState>proc(ProcessState::self());
    //ProcessState::self()->setThreadPoolMaxThreadCount(1);
    ataFactoryService::instantiate();
    //ProcessState::self()->startThreadPool();

    IPCThreadState::self()->joinThreadPool();
    MMI_ALOGI("end factoryAtaService");
    return 0;
}

ProcessState 隐藏了更多的细节,稍后会与大家分享。

IPCThreadState-->joinThreadPool 就是一个事件管理器。会不停的与驱动通讯,等完成一些正常的事件循环。不能退出,如果退出了,则服务就结束了。

那么如何使用cpp代码与服务端通讯呢??

static sp<IAtaFactoryService> mFactoryAta;
static bool getFactoryAtaService() {
    if (mFactoryAta == nullptr) {
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder = sm->getService(String16("factory.ataService"));

        mFactoryAta = interface_cast<IAtaFactoryService>(binder);
    };
    return mFactoryAta == nullptr ? false : true;
}

其实就是从serviceManager 中获取服务,其实这个获取的是一个BpBInder 类。

然后这时我们就可以通过mFactoryAta 来调用服务端的函数。

bool factoryAtaUtils::metaCtr(string inStr, string &outStr) {

    if (getFactoryAtaService()) {
        String16 rt_str;
        mFactoryAta->metaCtr(String16(inStr.c_str()), &rt_str);
        String8 tmp(rt_str);
        if (tmp.isEmpty() || tmp.contains("error")) {
            return false;
        }
        outStr.append(tmp.string());
        return true;
    }
    return false;
}

本来想把所有的细节都给大家讲讲但是,但是写着写着发现,貌似挺多的。今天大家先熟悉一下如何使用吧!

猜你喜欢

转载自blog.csdn.net/haozhenghui10/article/details/81431615