編輯:關於Android編程
本文參考《Android系統源代碼情景分析》,作者羅升陽
一、測試代碼:
~/Android/external/binder/server
----FregServer.cpp
~/Android/external/binder/common
----IFregService.cpp
----IFregService.h
~/Android/external/binder/client
----FregClient.cpp
Binder庫(libbinder)代碼:
~/Android/frameworks/base/libs/binder
----BpBinder.cpp
----Parcel.cpp
----ProcessState.cpp
----Binder.cpp
----IInterface.cpp
----IPCThreadState.cpp
----IServiceManager.cpp
----Static.cpp
~/Android/frameworks/base/include/binder
----Binder.h
----BpBinder.h
----IInterface.h
----IPCThreadState.h
----IServiceManager.h
----IBinder.h
----Parcel.h
----ProcessState.h
驅動層代碼:
~/Android//kernel/goldfish/drivers/staging/android
----binder.c
----binder.h
二、源碼分析
繼續上一篇Android Binder進程間通信---注冊Service組件---發送和處理BC_REPLY返回協議http://blog.csdn.net/jltxgcy/article/details/26339313,執行完waitForResponse函數,參考Android Binder進程間通信---注冊Service組件---Client發送BC_TRANSACTION。應該返回IPCThreadState類的transact方法,再返回BpBinder類的transact函數,最後返回BpServiceManager類addService函數。最後再返回FregService類的main函數,實現如下:
~/Android/external/binder/server
----FregServer.cpp
int main(int argc, char** argv) { FregService::instantiate(); ProcessState::self()->startThreadPool();//啟動一個Binder線程池 IPCThreadState::self()->joinThreadPool();//主線程加入線程池 return 0; }首先當前進程的ProcessState對象的成員函數startThreadPool來啟動一個Binder線程池,接著繼續調用當前線程的IPCThreadState對象的成員函數joinThreadPool,將當前線程加入到前面所啟動的Binder線程池中去等待和處理來自Client進程的進程間通信請求。
下面我們就分析ProcessState類的成員函數startThreadPool的實現,在分析過程中,同時也會分析IPCThreadState類的成員函數joinThreadPool的實現。
ProcessState類的成員函數startThreadPool的實現如下:
~/Android/frameworks/base/libs/binder
----ProcessState.cpp
void ProcessState::startThreadPool() { AutoMutex _l(mLock); if (!mThreadPoolStarted) {//默認值為false mThreadPoolStarted = true;//防止它的成員函數spawnPooledThread被重復調用來啟動Binder線程池 spawnPooledThread(true); } }當前進程的ProcessState對象的成員變量mThreadPoolStarted被初始化為false,當它將一個Binder線程池啟動起來之後,就會將內部的成員變量mThreadPoolStarted的值設置為true,防止它的成員函數spawnPooledThread被重復調用來啟動Binder線程池。spawnPooledThread函數實現如下:
~/Android/frameworks/base/libs/binder
----ProcessState.cpp
void ProcessState::spawnPooledThread(bool isMain) { if (mThreadPoolStarted) { int32_t s = android_atomic_add(1, &mThreadPoolSeq); char buf[32]; sprintf(buf, "Binder Thread #%d", s); LOGV("Spawning new pooled thread, name=%s\n", buf); sp創建了一個PoolThread對象t,調用它的成員函數run來啟動一個新的線程。t = new PoolThread(isMain);//isMain為true t->run(buf);//啟動一個新的線程 } }
PoolThread類繼承了線程類Thread,並且重寫了它的線程入口成員函數threadLoop,因此當一個PoolThread對象t所對應的線程啟動起來之後,它的成員函數threadLoop就會被調用。實現如下:
~/Android/frameworks/base/libs/binder
----ProcessState.cpp
class PoolThread : public Thread { public: PoolThread(bool isMain) : mIsMain(isMain)//isMain為true { } protected: virtual bool threadLoop() { IPCThreadState::self()->joinThreadPool(mIsMain);//isMain為true return false; } const bool mIsMain; };和主線程一樣調用了IPCThreadState類的成員函數joinThreadPool。實現如下:
~/Android/frameworks/base/libs/binder
----IPCThreadState.cpp
void IPCThreadState::joinThreadPool(bool isMain)//默認值為true { ......... mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);//isMain為true,BC_ENTER_LOOPER ........ status_t result; do { int32_t cmd; ....... result = talkWithDriver();//將自己注冊到Binder線程池中,一個無線循環中不斷等待進程間通信請求 if (result >= NO_ERROR) { size_t IN = mIn.dataAvail(); if (IN < sizeof(int32_t)) continue; cmd = mIn.readInt32(); ........ result = executeCommand(cmd);//處理進程間通信請求 } ......... if(result == TIMED_OUT && !isMain) {//一直為false,因為isMain為true break; } } while (result != -ECONNREFUSED && result != -EBADF); ........ mOut.writeInt32(BC_EXIT_LOOPER);//退出Binder線程池 talkWithDriver(false); }參數isMain是一個默認參數,它的默認值為true。從前面的調用過程可以知道,無論是FregServer進程的主線程,還是FregServer進程剛才所創建的線程,它們都是主動(isMain為true)請求加入到Binder線程池的,即它們都不是由於Binder驅動程序請求創建而加入到Binder線程池的。
一個Binder線程的生命周期可以劃分為三個階段:
第一階段是將自己注冊到Binder線程池中;
第二階段是一個無線循環中不斷等待和處理進程間通信請求;
第三階段是退出Binder線程池。
最後執行完的結果是FregServer有兩個線程,睡眠等待進程間通信數據的到來。
恰逢2014 Google I/O大會,不難看出安卓在Google的推進以及本身的開放性作用下,已經快延生到生活的各個方面了,從安卓智能手機、平板,到可穿戴的Androi
首先聲明一點: 這裡的多線程下載並不是指多個線程下載一個 文件,而是每個線程負責一個文件,今天給大家分享一個多線程下載的 例子。先看一下效果,點擊下載開始下載,同時顯示下
五一放假,閒著沒事,裝了最新的ubutun16.04,然後打算順道把android開發環境移植到ubuntu上來體驗一下。 1.首先下載了Android stu
本文實例講述了Android編程布局控件之AbsoluteLayout用法。分享給大家供大家參考,具體如下:AbsoluteLayout是絕對布局管理器,指的是指定組件的