在Binder: ServiceManager的获取文章中,分析了ProcessState
与IPCThreadState
的创建过程。最后在defaultServiceManager
中,返回的是持有BpBinder
的BpServiceManager
对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| int main(int argc __unused, char **argv __unused) { signal(SIGPIPE, SIG_IGN); sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm(defaultServiceManager()); // BpServiceManager ALOGI("ServiceManager: %p", sm.get()); AIcu_initializeIcuOrDie(); MediaPlayerService::instantiate(); ResourceManagerService::instantiate(); registerExtensions(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); } void MediaPlayerService::instantiate() { defaultServiceManager()->addService( String16("media.player"), new MediaPlayerService()); }
|
所以在instantiate
方法中调用的addService
其实是BpServiceManager
中的方法,将名称为media.player
的MediaPlayerService
对象进行注册
addService
下面我们直接看BpServiceManager
中的addService
。
1 2 3 4 5 6 7 8 9 10 11 12 13
| virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated, int dumpsysPriority) { // 封装成Parcel对象 Parcel data, reply; data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); data.writeString16(name); data.writeStrongBinder(service); data.writeInt32(allowIsolated ? 1 : 0); data.writeInt32(dumpsysPriority); // 发送数据到远端 status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); return err == NO_ERROR ? reply.readExceptionCode() : err; }
|
这里将数据统一封装到Parcel
对象中,最后通过remote()
的transact
方法将数据传输到远端,对应的code
为ADD_SERVICE_TRANSACTION
。
现在我们在来看下remote()
到底是什么。
它是BpServiceManager
中的一个方法,这个方法来自于它的父类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class BpServiceManager : public BpInterface<IServiceManager> public: explicit BpServiceManager(const sp<IBinder>& impl) // BpBinder(0) : BpInterface<IServiceManager>(impl) {} inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote) : BpRefBase(remote) BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()), mRefs(nullptr), mState(0) 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() { return mRemote; } inline IBinder* remote() const { return mRemote; } private: BpRefBase(const BpRefBase& o); BpRefBase& operator=(const BpRefBase& o); IBinder* const mRemote; RefBase::weakref_type* mRefs; std::atomic<int32_t> mState; };
|
从上面继承流程可以得到这个remote()
返回的就是mRemote
,而mRemote
其实是最开始的参数BpBinder(0)
。说明这里调用的是BpBinder
的transact
方法
1 2 3 4 5 6 7 8 9 10 11 12 13
| status_t BpBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { // Once a binder has died, it will never come back to life. if (mAlive) { status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags); if (status == DEAD_OBJECT) mAlive = 0; return status; } return DEAD_OBJECT; }
|
进入BpBinder
发现又转调到IPCThreadState
的transact
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { ... // 传输数据 err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr); if ((flags & TF_ONE_WAY) == 0) { ... if (reply) { // 等待远程数据的返回 err = waitForResponse(reply); } else { Parcel fakeReply; err = waitForResponse(&fakeReply); } } else { err = waitForResponse(nullptr, nullptr); } return err; }
|
这里主要做的就两件事
- 通过
writeTransactionData
将数据写入到Parcel
中,对应的cmd
命令为BC_TRANSACTION
,这是请求码,对应的都是以BC_
开头命名,在service
端会通过这些请求码做不同的逻辑处理。
- 通过
waitForResponse
来等待远端的数据返回,这里也有一个cmd
命令行,例如BR_REPLY
,这是返回码,对应的都是以BR_
开头命名的,在client
也会通过这些返回码做不同的逻辑处理。
今天我们不研究这几个方法,后续文章会专门分析数据的交互。
到这里MediaPlayerService
已经注册完毕,我们接下最前面的main
方法继续往下走。
startThreadPool
1
| ProcessState::self()->startThreadPool();
|
又是ProcessState
中的方法,进入startThreadPooll
中看一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| void ProcessState::startThreadPool() { AutoMutex _l(mLock); if (!mThreadPoolStarted) { mThreadPoolStarted = true; spawnPooledThread(true); } } void ProcessState::spawnPooledThread(bool isMain) { if (mThreadPoolStarted) { String8 name = makeBinderThreadName(); // 开启binder线程池 sp<Thread> t = new PoolThread(isMain); t->run(name.string()); } }
|
在spawnPooledThread
方法中创建了PoolThread
线程池,它继承于Thread
,最后调用了线程的run
方法
joinThreadPool
1
| IPCThreadState::self()->joinThreadPool();
|
继续看joinThreadPooll
方法, 它在IPCThreadState
中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| void IPCThreadState::joinThreadPool(bool isMain) { mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); status_t result; do { processPendingDerefs(); // 等待命令行的到来 result = getAndExecuteCommand(); } while (result != -ECONNREFUSED && result != -EBADF); mOut.writeInt32(BC_EXIT_LOOPER); // 与binder驱动通信 talkWithDriver(false); }
|
这里主要的方法是getAndExecuteCommand()
,它是用来处理接收service
端发送过来的数据,因为service
与client
是可以互相发起数据的交互。这个时候client
就相当于service
,它开启轮询不断地监听service
发过来的数据。最终它会调用executeCommand
来统一处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| status_t IPCThreadState::executeCommand(int32_t cmd) { switch ((uint32_t)cmd) { ... case BR_TRANSACTION_SEC_CTX: case BR_TRANSACTION: { ... if (tr.target.ptr) { if (reinterpret_cast<RefBase::weakref_type*>( tr.target.ptr)->attemptIncStrong(this)) { // BBinder error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer, &reply, tr.flags); reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this); } else { error = UNKNOWN_TRANSACTION; } } else { error = the_context_object->transact(tr.code, buffer, &reply, tr.flags); } ... if ((tr.flags & TF_ONE_WAY) == 0) { // 向服务端发送回应reply,注意这里的0,特定标识; sendReply(reply, 0); } else { LOG_ONEWAY("NOT sending reply to %d!", mCallingPid); } ... } break; ... default: ALOGE("*** BAD COMMAND %d received from Binder driver\n", cmd); result = UNKNOWN_ERROR; break; } if (result != NO_ERROR) { mLastError = result; } return result; }
|
为了简化代码只展示了主要的一部分代码,BR_TRANSACTION
类似于上面所说的BC_TRANSACTION
,这里代表的是从服务端有数据发送过来,说明服务端主动传输数据。
所以这个时候就与service
端建立了通信。
至此在client
端的数据交互流程已经分析完毕,后续我们再来看binder
传输过程中的service
端,看它是如何接收与处理数据的。
推荐
android_startup: 提供一种在应用启动时能够更加简单、高效的方式来初始化组件。开发人员可以使用android-startup
来简化启动序列,并显式地设置初始化顺序与组件之间的依赖关系。 与此同时android-startup
支持同步与异步等待,并通过有向无环图拓扑排序的方式来保证内部依赖组件的初始化顺序。
AwesomeGithub: 基于Github
客户端,纯练习项目,支持组件化开发,支持账户密码与认证登陆。使用Kotlin
语言进行开发,项目架构是基于Jetpack&DataBinding
的MVVM
;项目中使用了Arouter
、Retrofit
、Coroutine
、Glide
、Dagger
与Hilt
等流行开源技术。
flutter_github: 基于Flutter
的跨平台版本Github
客户端,与AwesomeGithub
相对应。
android-api-analysis: 结合详细的Demo
来全面解析Android
相关的知识点, 帮助读者能够更快的掌握与理解所阐述的要点。
daily_algorithm: 算法进阶,由浅入深,欢迎加入一起共勉。