Um: Introdução ao mecanismo de encadernação
O mecanismo Binder é um mecanismo de comunicação entre processos fornecido pelo sistema Android. O processo Cliente espera se comunicar com o processo Servidor, mas por ser um processo cruzado, ele precisa se comunicar com o processo do driver Binder.
O Binder consiste nos seguintes módulos:
* Driver de fichário
* Processo Binder Servidor-Servidor
* Processo Binder Cliente-Cliente
* ServiceManager - Gerente
O modelo de comunicação do Binder é o seguinte:
Dois: Crie um modelo de serviço
Se você deseja criar um Serviço, você precisa que o Servidor herde BnInterface e o Cliente herde BpInterface. Especificamente, pode ser representado pela seguinte figura:
Declarações relacionadas a Bn, Bp podem ser encontradas nos seguintes documentos
frameworks/native/libs/binder/include/binder/IInterface.h
frameworks/native/libs/binder/include/binder/IBinder.h
O código específico é o seguinte
frameworks/native/libs/binder/include/binder/IInterface.h
class IInterface : public virtual RefBase
{
public:
IInterface();
static sp<IBinder> asBinder(const IInterface*);
static sp<IBinder> asBinder(const sp<IInterface>&);
protected:
virtual ~IInterface();
virtual IBinder* onAsBinder() = 0;
};
-----------------------------------------------------------
class BnInterface : public INTERFACE, public BBinder
{
public:
virtual sp<IInterface> queryLocalInterface(const String16& _descriptor);
virtual const String16& getInterfaceDescriptor() const;
protected:
typedef INTERFACE BaseInterface;
virtual IBinder* onAsBinder();
};
frameworks/native/libs/binder/include/binder/Binder.h
class BBinder : public IBinder
{
public:
BBinder();
virtual const String16& getInterfaceDescriptor() const;
virtual bool isBinderAlive() const;
virtual status_t pingBinder();
...
};
frameworks/native/libs/binder/include/binder/IBinder.h
class [[clang::lto_visibility_public]] IBinder : public virtual RefBase
{
public:
enum {
FIRST_CALL_TRANSACTION = 0x00000001,
LAST_CALL_TRANSACTION = 0x00ffffff,
...
};
-------------------------------------------------------------------
class BpInterface : public INTERFACE, public BpRefBase
{
public:
explicit BpInterface(const sp<IBinder>& remote);
protected:
typedef INTERFACE BaseInterface;
virtual IBinder* onAsBinder();
};
frameworks/native/libs/binder/include/binder/Binder.h
class BpRefBase : public virtual RefBase
{
protected:
explicit BpRefBase(const sp<IBinder>& o);
virtual ~BpRefBase();
virtual void onFirstRef();
virtual void onLastStrongRef(const void* id);
virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
inline IBinder* remote() const { return mRemote; }//返回的是BpBinder
inline sp<IBinder> remoteStrong() const { return sp<IBinder>::fromExisting(mRemote); ...
Três: O transportador de transferência de dados entre processos - Parcela
O código do Parcel está localizado no diretório a seguir e o Parcel é usado para transferir dados entre processos. Quer o Cliente envie dados para o Servidor ou o Servidor envie dados para o Cliente, eles são transmitidos através do Parcel.
frameworks/native/include/binder/Parcel.h
frameworks/native/include/binder/Parcel.cpp
escreva interfaces relacionadas:
status_t write(const void* data, size_t len);
status_t writeInt32(int32_t val);
status_t writeUint32(uint32_t val);
status_t writeInt64(int64_t val);
status_t writeUint64(uint64_t val);
status_t writeFloat(float val);
status_t writeDouble(double val);
status_t writeStrongBinder(const sp<IBinder>& val);
status_t writeInt32Array(size_t len, const int32_t *val);
status_t writeByteArray(size_t len, const uint8_t *val);
status_t writeBool(bool val);
status_t writeChar(char16_t val);
status_t writeByte(int8_t val);
......
leia interfaces relacionadas:
status_t read(void* outData, size_t len) const;
const void* readInplace(size_t len) const;
int32_t readInt32() const;
status_t readInt32(int32_t *pArg) const;
uint32_t readUint32() const;
status_t readUint32(uint32_t *pArg) const;
int64_t readInt64() const;
status_t readInt64(int64_t *pArg) const;
uint64_t readUint64() const;
status_t readUint64(uint64_t *pArg) const;
float readFloat() const;
status_t readFloat(float *pArg) const;
double readDouble() const;
status_t readDouble(double *pArg) const;
bool readBool() const;
status_t readBool(bool *pArg) const;
char16_t readChar() const;
status_t readChar(char16_t *pArg) const;
int8_t readByte() const;
status_t readByte(int8_t *pArg) const;
......
Por exemplo, como transferir dados através do Parcel no serviço nativo, conforme mostrado abaixo, são todos transferidos através do Parcel.
class BpCustomizeManagerService : public BpInterface<ICustomizeManagerService>
{
public:
explicit BpCustomizeManagerService (const sp<IBinder>& impl)
: BpInterface <ICustomizeManagerService>(impl)
{
ALOGD("create Service \n");
}
int customeize(int size){
Parcel data, reply;
data.writeInterfaceToken(ICustomizeManagerService::getInterfaceDescriptor());
data.writeInt32(size);
remote()->transact(CUSTOMIZE, data, &reply);
return reply.readInt32();
}
};
status_t BnCustomizeManagerService ::onTransact(uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags){
switch (code)
{
case CUSTOMIZE:
{
CHECK_INTERFACE(ICustomizeManagerService, data, reply);
int size = data.readInt32();
int ret = customeize(size);
//函数返回值从Server传递给Client
reply->writeInt32();
return NO_ERROR;
}
...
};