StrongBinder对客户端来说就是一个远端服务。
下面通过一个例子来说明。
首先我们在第一个应用程序中注册一个自己的服务。然后在第二个应用程序中给这个服务注册一个 StrongBinder,这个StrongBinder是另外的一个服务,然后在第3个应用程序中获取第一个注册的服务,通过这个服务读取这个StrongBinder,也就是说第3个应用程序中可以获取到第二个服务,然后调用这个服务的一个接口。
#include <utils/Trace.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <iostream>
#include <stdint.h>
#include <sys/types.h>
#include <set>
#include <thread>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <inttypes.h>
#include <cutils/properties.h>
#include <utils/Log.h>
#include <utils/SystemClock.h>
#include <android-base/properties.h>
#include <errno.h>
#include <fcntl.h>
#include <fstream>
#include <poll.h>
#include <pthread.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/Binder.h>
#include <binder/IBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/IServiceManager.h>
#include <sys/wait.h>
#include <private/binder/binder_module.h>
#include <sys/epoll.h>
#include <sys/prctl.h>
using namespace android;
using namespace std;
enum BinderLibTestTranscationCode {
BINDER_LIB_TEST_NOP_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
BINDER_LIB_TEST_REGISTER_SERVER,
BINDER_LIB_TEST_ADD_SERVER,
};
static String16 binderLibTestServiceName = String16("test.binderLib.0921");
class BinderLibTestService: public BBinder {
public:
explicit BinderLibTestService(int32_t id) :
m_id(id), m_nextServerId(id + 1), m_serverStartRequested(false), m_callback(
nullptr) {
pthread_mutex_init(&m_serverWaitMutex, nullptr);
pthread_cond_init(&m_serverWaitCond, nullptr);
}
~BinderLibTestService() {
exit(EXIT_SUCCESS);
}
virtual status_t onTransact(uint32_t code, const Parcel &data,
Parcel *reply, uint32_t flags = 0) override {
printf("%s: code %d\n", __func__, code);
(void) flags;
// if (getuid() != (uid_t) IPCThreadState::self()->getCallingUid()) {
// return PERMISSION_DENIED;
// }
switch (code) {
case BINDER_LIB_TEST_REGISTER_SERVER: {
int32_t id;
sp<IBinder> binder;
id = data.readInt32();
binder = data.readStrongBinder();
if (binder == nullptr) {
return BAD_VALUE;
}
if (m_id != 0)
return INVALID_OPERATION;
m_serverStarted = binder;
printf("BINDER_LIB_TEST_REGISTER_SERVER success\n");
return NO_ERROR;
}
case BINDER_LIB_TEST_ADD_SERVER: {
if (m_serverStarted == nullptr) {
printf("m_serverStarted is null\n");
return NO_ERROR;
}
reply->writeStrongBinder(m_serverStarted);
reply->writeInt32(100);
// m_serverStarted = nullptr;
int ret = NO_ERROR;
printf("BINDER_LIB_TEST_ADD_SERVER success\n");
return ret;
}
case BINDER_LIB_TEST_NOP_TRANSACTION:
cout
<< "BinderLibTestService 01 onTransact BINDER_LIB_TEST_NOP_TRANSACTION"
<< endl;
return NO_ERROR;
default:
return UNKNOWN_TRANSACTION;
};
}
private:
int32_t m_id;
int32_t m_nextServerId;
pthread_mutex_t m_serverWaitMutex;
pthread_cond_t m_serverWaitCond;
bool m_serverStartRequested;
sp<IBinder> m_serverStarted;
sp<IBinder> m_strongRef;
sp<IBinder> m_callback;
};
int main(int argc, char **argv) {
ProcessState::self()->startThreadPool();
printf("10\n");
status_t ret;
sp<IServiceManager> sm = defaultServiceManager();
BinderLibTestService *testServicePtr;
int index = 0;
sp<BinderLibTestService> testService = new BinderLibTestService(index);
printf("addService\n");
ret = sm->addService(binderLibTestServiceName, testService);
printf("end\n");
IPCThreadState::self()->joinThreadPool();
return 0;
}
第二个应用程序:
#include <ui/DisplayConfig.h>
#include <gui/IRegionSamplingListener.h>
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceControl.h>
#include <gui/Surface.h>
#include <private/gui/ComposerService.h>
#include <gui/SurfaceComposerClient.h>
#include <android/native_window.h>
#include <utils/Trace.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <iostream>
#include <stdint.h>
#include <sys/types.h>
#include <set>
#include <thread>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <inttypes.h>
#include <cutils/properties.h>
#include <utils/Log.h>
#include <utils/SystemClock.h>
#include <android-base/properties.h>
#include <errno.h>
#include <fcntl.h>
#include <fstream>
#include <poll.h>
#include <pthread.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/Binder.h>
#include <binder/IBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/IServiceManager.h>
#include <sys/wait.h>
#include <private/binder/binder_module.h>
#include <sys/epoll.h>
#include <sys/prctl.h>
using namespace android;
using namespace std;
enum BinderLibTestTranscationCode {
BINDER_LIB_TEST_NOP_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
BINDER_LIB_TEST_REGISTER_SERVER,
BINDER_LIB_TEST_ADD_SERVER,
};
static String16 binderLibTestServiceName = String16("test.binderLib.0921");
class BinderLibTestService: public BBinder {
public:
explicit BinderLibTestService(int32_t id)
{
}
~BinderLibTestService() {
exit(EXIT_SUCCESS);
}
virtual status_t onTransact(uint32_t code, const Parcel &data,
Parcel *reply, uint32_t flags = 0) override {
printf("%s: code %d\n", __func__, code);
(void) flags;
switch (code) {
case BINDER_LIB_TEST_NOP_TRANSACTION:
reply->writeInt32(data.readInt32()+data.readInt32());
cout
<< "BinderLibTestService 02 onTransact BINDER_LIB_TEST_NOP_TRANSACTION"
<< endl;
return NO_ERROR;
default:
return UNKNOWN_TRANSACTION;
};
}
private:
};
int main(int argc, char **argv) {
ProcessState::self()->startThreadPool();
sp<IServiceManager> sm = defaultServiceManager();
int index = 1 ;
int ret;
sp<IBinder> server = sm->getService(binderLibTestServiceName);
sp<BinderLibTestService> testService = new BinderLibTestService(index);
Parcel data, reply;
data.writeInt32(index);
data.writeStrongBinder(testService);
printf("writeStrongBinder testService\n");
ret = server->transact(BINDER_LIB_TEST_REGISTER_SERVER, data, &reply);
printf("writeStrongBinder ret %d\n",ret);
printf("end\n");
IPCThreadState::self()->joinThreadPool();
return 0;
}
第3个应用程序也是客户端:
#include <utils/Trace.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <iostream>
#include <stdint.h>
#include <sys/types.h>
#include <set>
#include <thread>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <inttypes.h>
#include <cutils/properties.h>
#include <utils/Log.h>
#include <utils/SystemClock.h>
#include <android-base/properties.h>
#include <errno.h>
#include <fcntl.h>
#include <fstream>
#include <poll.h>
#include <pthread.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/Binder.h>
#include <binder/IBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/IServiceManager.h>
#include <sys/wait.h>
#include <private/binder/binder_module.h>
#include <sys/epoll.h>
#include <sys/prctl.h>
using namespace android;
using namespace std;
enum BinderLibTestTranscationCode {
BINDER_LIB_TEST_NOP_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
BINDER_LIB_TEST_REGISTER_SERVER,
BINDER_LIB_TEST_ADD_SERVER,
};
static String16 binderLibTestServiceName = String16("test.binderLib.0921");
int main(int argc, char **argv) {
ProcessState::self()->startThreadPool();
printf("02\n");
sp<IServiceManager> sm = defaultServiceManager();
int index = 1;
int ret;
sp<IBinder> server = sm->getService(binderLibTestServiceName);
Parcel data, reply;
printf("writeStrongBinder testService\n");
ret = server->transact(BINDER_LIB_TEST_ADD_SERVER, data, &reply);
sp<IBinder> binder;
printf("readStrongBinder 0\n");
binder = reply.readStrongBinder();
printf("readStrongBinder 1\n");
if (binder == nullptr) {
printf("binder==nullptr 1\n");
return -1;
}
Parcel data1, reply1;
data1.writeInt32(11);
data1.writeInt32(12);
ret = binder->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data1, &reply1);
printf(" reply1.readInt32(): %d\n", reply1.readInt32()); // 23
printf("writeStrongBinder ret %d\n", ret);
IPCThreadState::self()->joinThreadPool();
return 0;
}
依次编译运行3个应用程序,会发现最终的客户端打印值为23,说明成功调用了我们第二个的服务。