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通讯简单的使用则包含一个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;
}
本来想把所有的细节都给大家讲讲但是,但是写着写着发现,貌似挺多的。今天大家先熟悉一下如何使用吧!