android系統(tǒng)架構設計與軟硬整合_第1頁
android系統(tǒng)架構設計與軟硬整合_第2頁
android系統(tǒng)架構設計與軟硬整合_第3頁
android系統(tǒng)架構設計與軟硬整合_第4頁
android系統(tǒng)架構設計與軟硬整合_第5頁
已閱讀5頁,還剩97頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

By王家林Android系統(tǒng)架構設計與軟硬整合MediaPlayerService的類圖MediaPlayerService的類圖MediaPlayerService繼承于BnMediaPlayerService類,BnMediaPlayerService是一個BinderNative類,用來處理Client請求的;BnMediaPlayerService繼承于BnInterface<IMediaPlayerService>類;BnInterfaceBnInterface是一個模板類,它定義在frameworks/base/include/binder/IInterface.h文件中:BnMediaPlayerService實際是繼承了IMediaPlayerService和BBinder類。IMediaPlayerService和BBinder類又分別繼承了IInterface和IBinder類,IInterface和IBinder類又同時繼承了RefBase類;實際上,BnMediaPlayerService并不是直接接收到Client處發(fā)送過來的請求,而是使用了IPCThreadState接收Client處發(fā)送過來的請求,而IPCThreadState又借助了ProcessState類來與Binder驅動程序交互;IPCThreadState接收到了Client處的請求后,就會調用BBinder類的transact函數(shù),并傳入相關參數(shù),BBinder類的transact函數(shù)最終調用BnMediaPlayerService類的onTransact函數(shù),于是,就開始真正地處理Client的請求;5MediaPlayerService啟動MediaPlayerService的代碼位于frameworks/base/media/mediaserver/main_mediaserver.cpp文件中:

6p<ProcessState>

proc(ProcessState::self());

代碼的作用是通過ProcessState::self()調用創(chuàng)建一個ProcessState實例。ProcessState::self()是ProcessState類的一個靜態(tài)成員變量,定義在frameworks/base/libs/binder/ProcessState.cpp文件中:可以看出,這個函數(shù)作用是返回一個全局唯一的ProcessState實例gProcess。全局唯一實例變量gProcess定義在frameworks/base/libs/binder/Static.cpp文件中:MutexgProcessMutex;sp<ProcessState>gProcess;7ProcessStateProcessState的構造函數(shù):通過open_driver函數(shù)打開Binder設備文件/dev/binder,并將打開設備文件描述符保存在成員變量mDriverFD中;二是通過mmap來把設備文件/dev/binder映射到內存中;8open_driver函數(shù)open_driver函數(shù)的實現(xiàn)同樣位于frameworks/base/libs/binder/ProcessState.cpp文件中;這個函數(shù)的作用主要是通過open文件操作函數(shù)來打開/dev/binder設備文件,然后再調用ioctl文件控制函數(shù)來分別執(zhí)行BINDER_VERSION和BINDER_SET_MAX_THREADS兩個命令來和Binder驅動程序進行交互,前者用于獲得當前Binder驅動程序的版本號,后者用于通知Binder驅動程序,MediaPlayerService最多可同時啟動15個線程來處理Client端的請求;打開/dev/binder設備文件后,Binder驅動程序就為MediaPlayerService進程創(chuàng)建了一個structbinder_proc結構體實例來維護MediaPlayerService進程上下文相關信息;9MediaPlayerService::instantiate進入到MediaPlayerService::instantiate函數(shù)把MediaPlayerService添加到ServiceManger中去了。這個函數(shù)定義在frameworks/base/media/libmediaplayerservice/MediaPlayerService.cpp文件中;10BpServiceManger::addServiceBpServiceManger::addService的實現(xiàn)函數(shù)frameworks/base/libs/binder/IServiceManager.cpp文件:

IServiceManager::getInterfaceDescriptor()返回來的是一個字符串,即"android.os.IServiceManager“11BpBinder::transact函數(shù)

這里又調用了IPCThreadState::transact進執(zhí)行實際的操作。注意,這里的mHandle為0,code為ADD_SERVICE_TRANSACTION。ADD_SERVICE_TRANSACTION是上面以參數(shù)形式傳進來的,那mHandle為什么是0呢?因為這里表示的是ServiceManager遠程接口,它的句柄值一定是0;12IPCThreadState::transact函數(shù)

IPCThreadState::transact函數(shù)的參數(shù)flags是一個默認值為0的參數(shù),上面沒有傳相應的實參進來,因此,這里就為0。

函數(shù)首先調用writeTransactionData函數(shù)準備好一個struct

binder_transaction_data結構體變量,這個是等一下要傳輸給Binder驅動程序的;13waitForResponseIPCThreadState::transact函數(shù)中,接下去看,(flags&TF_ONE_WAY)==0為true,并且reply不為空,所以最終進入到waitForResponse(reply)這條路徑來;主要調用了talkWithDriver函數(shù)來與Binder驅動程序進行交互:14talkWithDriver這里doReceive和needRead均為1告訴Binder驅動程序,先執(zhí)行write操作,再執(zhí)行read操作;15Binder通信關鍵的地方

t->buffer->data所指向的地址是內核空間的,現(xiàn)在要把數(shù)據(jù)返回給ServiceManager進程的用戶空間,而ServiceManager進程的用戶空間是不能訪問內核空間的數(shù)據(jù)的,所以這里要作一下處理。怎么處理呢?我們在學面向對象語言的時候,對象的拷貝有深拷貝和淺拷貝之分,深拷貝是把另外分配一塊新內存,然后把原始對象的內容搬過去,淺拷貝是并沒有為新對象分配一塊新空間,而只是分配一個引用,而個引用指向原始對象。Binder機制用的是類似淺拷貝的方法,通過在用戶空間分配一個虛擬地址,然后讓這個用戶空間虛擬地址與

t->buffer->data這個內核空間虛擬地址指向同一個物理地址,這樣就可以實現(xiàn)淺拷貝了。這里只要將t->buffer->data加上一個偏移值proc->user_buffer_offset就可以得到t->buffer->data對應的用戶空間虛擬地址了。調整了tr.data.ptr.buffer的值之后,不要忘記也要一起調整tr.data.ptr.offsets的值。16MediaPlayerService、ServiceManager和BinderDriver之間的交互main_mediaserver.cpp文件中的main函數(shù)ProcessState::self()->startThreadPool();IPCThreadState::self()->joinThreadPool();18ProcessState::startThreadPool這里調用spwanPooledThread:

接著主要是創(chuàng)建一個線程,PoolThread繼續(xù)Thread類,Thread類定義在frameworks/base/libs/utils/Threads.cpp文件中,其run函數(shù)最終調用子類的threadLoop函數(shù)19joinThreadPool

這個函數(shù)最終是在一個無窮循環(huán)中,通過調用talkWithDriver函數(shù)來和Binder驅動程序進行交互,實際上就是調用talkWithDriver來等待Client的請求,然后再調用mand來處理請求,而在mand函數(shù)中,最終會調用BBinder::transact來真正處理Client的請求;20mand具體代碼見備注21BBinder::transact的實現(xiàn)最終會調用onTransact函數(shù)來處理。在這個場景中,BnMediaPlayerService繼承了BBinder類,并且重載了onTransact函數(shù),因此,這里實際上是調用了BnMediaPlayerService::onTransact函數(shù);22BnMediaPlayerService::onTransact這個函數(shù)定義在frameworks/base/libs/media/libmedia/IMediaPlayerService.cpp文件中;Server啟動起來之后,就會在一個無窮循環(huán)中等待Client的請求;23以MediaPlayer來說明Binder中的Client獲得Server遠程接口過程MediaPlayer了,它聲明和實現(xiàn)在frameworks/base/include/media/mediaplayer.h和frameworks/base/media/libmedia/mediaplayer.cpp文件中。MediaPlayer繼承于IMediaDeathNotifier類,這個類聲明和實現(xiàn)在frameworks/base/include/media/IMediaDeathNotifier.h和frameworks/base/media/libmedia//IMediaDeathNotifier.cpp文件中,里面有一個靜態(tài)成員函數(shù)getMeidaPlayerService,它通過IServiceManager::getService接口來獲得MediaPlayerService的遠程接口;BpMediaPlayerService的類圖BpMediaPlayerService的類圖從這個類圖可以看到,BpMediaPlayerService繼承于BpInterface<IMediaPlayerService>類,即BpMediaPlayerService繼承了IMediaPlayerService類和BpRefBase類,這兩個類又分別繼續(xù)了RefBase類。BpRefBase類有一個成員變量mRemote,它的類型為IBinder,實際是一個BpBinder對象。BpBinder類使用了IPCThreadState類來與Binder驅動程序進行交互,而IPCThreadState類有一個成員變量mProcess,它的類型為ProcessState,IPCThreadState類借助ProcessState類來打開Binder設備文件/dev/binder,因此,它可以和Binder驅動程序進行交互。BpMediaPlayerService的構造函數(shù)有一個參數(shù)impl,它的類型為constsp<IBinder>&,從上面的描述中,這個實際上就是一個BpBinder對象。這樣,要創(chuàng)建一個BpMediaPlayerService對象,首先就要有一個BpBinder對象。再來看BpBinder類的構造函數(shù),它有一個參數(shù)handle,類型為int32_t,這個參數(shù)的意義就是請求MediaPlayerService這個遠程接口的進程對MediaPlayerService這個Binder實體的引用了。因此,獲取MediaPlayerService這個遠程接口的本質問題就變?yōu)閺腟erviceManager中獲得MediaPlayerService的一個句柄了。IMediaDeathNotifier::getMeidaPlayerService函數(shù)首先通過defaultServiceManager函數(shù)來獲得ServiceManager的遠程接口,實際上就是獲得BpServiceManager的IServiceManager接口;27BpServiceManager::getServiceBpServiceManager::getService通過BpServiceManager::checkService執(zhí)行操作;

在BpServiceManager::checkService中,首先是通過Parcel::writeInterfaceToken往data寫入一個RPC頭就是寫往data里面寫入了一個整數(shù)和一個字符串“android.os.IServiceManager”,ServiceManager來處理CHECK_SERVICE_TRANSACTION請求之前,會先驗證一下這個RPC頭,看看是否正確。接著再往data寫入一個字符串name,這里就是“media.player”了。前面已經(jīng)往ServiceManager中注冊了一個名字為“media.player”的MediaPlayerService。28

IPCThreadState::talkWithDriver與Binder交互,找到ServiceManager的引用并喚醒ServiceManager;緩存ProcessState會把使用過的Binder遠程接口(BpBinder)緩存起來,這樣下次從ServiceManager那里請求得到相同的句柄(Handle)時就可以直接返回這個Binder遠程接口了,不用再創(chuàng)建一個出來。這里是第一次使用,因此,e->binder為空,于是創(chuàng)建了一個BpBinder對象:30IMediaDeathNotifier::getMediaPlayerService最后,函數(shù)返回到IMediaDeathNotifier::getMediaPlayerService這里,從這個語句返回binder

=

sm->getService(String16(“media.player”));

即binder

=

new

BpBinder(handle);

最后,函數(shù)調用:sMediaPlayerService=interface_cast<IMediaPlayerService>(binder);interface_cast這里的interface_cast實際上最終調用了IMediaPlayerService::asInterface函數(shù);

這里的obj就是BpBinder,而BpBinder::queryLocalInterface返回NULL,因此就創(chuàng)建了一個BpMediaPlayerService對象;

因此,我們最終就得到了一個BpMediaPlayerService對象,達到我們最初的目標。有了這個BpMediaPlayerService這個遠程接口之后,MediaPlayer就可以調用MediaPlayerService的服務。32Java中的ServiceManagerProxyJava中的ServiceManagerProxy這里可以看出,ServiceManagerProxy類實現(xiàn)了IServiceManager接口,IServiceManager提供了getService和addService兩個成員函數(shù)來管理系統(tǒng)中的Service。從ServiceManagerProxy類的構造函數(shù)可以看出,它需要一個BinderProxy對象的IBinder接口來作為參數(shù)。因此,要獲取ServiceManager的Java遠程接口ServiceManagerProxy,首先要有一個BinderProxy對象。ServiceManagerServiceManagerServiceManager類有一個靜態(tài)成員函數(shù)getIServiceManager,它的作用就是用來獲取ServiceManager的Java遠程接口了,而這個函數(shù)又是通過ServiceManagerNative來獲取ServiceManager的Java遠程接口的。ServiceManager.getIServiceManagerServiceManager.getIServiceManager這個函數(shù)的實現(xiàn)在frameworks/base/core/java/android/os/ServiceManager.java文件中:如果其靜態(tài)成員變量sServiceManager尚未創(chuàng)建,那么就調用ServiceManagerNative.asInterface函數(shù)來創(chuàng)建。在調用ServiceManagerNative.asInterface函數(shù)之前,首先要通過BinderInternal.getContextObject函數(shù)來獲得一個BinderProxy對象。37BinderInternal.getContextObjectBinderInternal.getContextObject的實現(xiàn)在/android/internal/os/BinderInternal.java文件中;

這里可以看出,BinderInternal.getContextObject是一個JNI方法;38BinderInternal.getContextObjectBinderInternal.getContextObject是一個JNI方法,它實現(xiàn)在frameworks/base/core/jni/android_util_Binder.cpp文件中:ProcessState::self()->getContextObject函數(shù)返回一個BpBinder對象,它的句柄值是0,即下面語句:sp<IBinder>

b

=

ProcessState::self()->getContextObject(NULL);

即sp<IBinder>

b

=

new

BpBinder(0);

39javaObjectForIBinder接著調用javaObjectForIBinder把這個BpBinder對象轉換成一個BinderProxy對象:40ServiceManager.getIServiceManagesServiceManager

=

ServiceManagerNative.asInterface(BinderInternal.getContextObject());

相當于sServiceManager

=

ServiceManagerNative.asInterface(new

BinderProxy());

ServiceManagerNative.asInterfaceServiceManagerNative.asInterface函數(shù)定義在frameworks/base/core/java/android/os/ServiceManagerNative.java文件中:這里的參數(shù)obj是一個BinderProxy對象,它的queryLocalInterface函數(shù)返回null。因此,最終以這個BinderProxy對象為參數(shù)創(chuàng)建一個ServiceManagerProxy對象。42ServiceManager.getIServiceManager返回到ServiceManager.getIServiceManager中,從下面語句返回:sServiceManager

=

ServiceManagerNative.asInterface(new

BinderProxy());

相當于sServiceManager

=

new

ServiceManagerProxy(new

BinderProxy());

總結在Java層,我們擁有了一個ServiceManager遠程接口ServiceManagerProxy,而這個ServiceManagerProxy對象在JNI層有一個句柄值為0的BpBinder對象與之通過gBinderProxyOffsets關聯(lián)起來。具有AIDL的示例:HelloService接口的定義編寫了一個硬件服務HelloService,它的服務接口定義在frameworks/base/core/java/android/os/IHelloService.aidl文件中;這個服務接口很簡單,只有兩個函數(shù),分別用來讀寫硬件寄存器;45IHelloService.aidl文件編譯后會生成一個IHelloService.java原來就是根據(jù)IHelloService接口的定義生成相應的Stub和Proxy類,這個就是的Binder機制的內容了,即實現(xiàn)這個HelloService的Server必須繼續(xù)于這里的IHelloService.Stub類,而這個HelloService的遠程接口就是這里的IHelloService.Stub.Proxy對象獲得的IHelloService接口。46HelloService接口的實現(xiàn)在/android/server目錄下實現(xiàn)一個HelloService.java文件

這里,我們可以看到,HelloService繼續(xù)了IHelloService.Stub類,它通過本地方法調用實現(xiàn)了getVal和setVal兩個函數(shù);47啟動HelloService在/android/server/SystemServer.java文件中,定義了SystemServer類。SystemServer對象是在系統(tǒng)啟動的時候創(chuàng)建的,它被創(chuàng)建的時候會啟動一個線程來創(chuàng)建HelloService,并且把它添加到ServiceManager中去;48HelloService的創(chuàng)建過程HelloService的創(chuàng)建過程:new

HelloService();

這個語句會調用HelloService類的構造函數(shù),而HelloService類繼承于IHelloService.Stub類,IHelloService.Stub類又繼承了Binder類,因此,最后會調用Binder類的構造函數(shù):這里調用了一個JNI方法init來初始化這個Binder對象;49init這個JNI方法定義在frameworks/base/core/jni/android_util_Binder.cpp文件中:

它實際上只做了一件事情,就是創(chuàng)建一個JavaBBinderHolder對象jbh,然后把這個對象的地址保存在上面的Binder類的mObject成員變量中;50ServiceManager.addService函數(shù)etIServiceManager函數(shù)我們在前面已經(jīng)分析過了,它返回的是一個ServiceManagerProxy對象的IServiceManager接口。因此,我們進入到ServiceManagerProxy.addService中去看看:51ServiceManagerProxy.addService這里的Parcel類是用Java來實現(xiàn)的,即用來在兩個進程之間傳遞數(shù)據(jù)。52Parcel.writeStrongBinder函數(shù)這里的writeStrongBinder函數(shù)又是一個JNI方法,它定義在frameworks/base/core/jni/android_util_Binder.cpp文件中:這里的clazz參數(shù)是一個Java語言實現(xiàn)的Parcel對象,通過parcelForJavaObject把它轉換成C++語言實現(xiàn)的Parcel對象。53ibinderForJavaObject

這里的object參數(shù)是一個Java語言實現(xiàn)的Binder對象,在調用C++語言實現(xiàn)的Parcel::writeStrongBinder把這個對象寫入到parcel對象時,首先通過ibinderForJavaObject函數(shù)把這個Java語言實現(xiàn)的Binder對象轉換為C++語言實現(xiàn)的JavaBBinderHolder對象:我們知道,這里的obj參數(shù)是一個Binder類的實例,因此,這里會進入到第一個if語句中去。在前面創(chuàng)建HelloService對象,曾經(jīng)在調用到HelloService的父類Binder中,曾經(jīng)在JNI層創(chuàng)建了一個JavaBBinderHolder對象,然后把這個對象的地址保存在Binder類的mObject成員變量中,因此,這里把obj對象的mObject成員變量強制轉為JavaBBinderHolder對象。54avaBBinderHolder::get這里是第一次調用get函數(shù),因此,會創(chuàng)建一個JavaBBinder對象,并且保存在mBinder成員變量中。注意,這里的mObject就是上面創(chuàng)建的HelloService對象了,這是一個Java對象。這個HelloService對象最終也會保存在JavaBBinder對象的成員變量mObject中。55mRemote這里的mRemote成員變量實際上是一個BinderProxy對象,因此,我們再來看看BinderProxy.transact函數(shù)的實現(xiàn):

這里的transact成員函數(shù)又是一個JNI方法,它定義在frameworks/base/core/jni/android_util_Binder.cpp文件中:56android_os_BinderProxy_transact

這里傳進來的參數(shù)dataObj和replyObj是一個Java接口實現(xiàn)的Parcel類,由于這里是JNI層,需要把它轉換為C++實現(xiàn)的Parcel類,它們就是通過我們前面說的parcelForJavaObject函數(shù)進行轉換的;57JNI接口中ServiceManager獲取ServiceManager遠程接口時,在JNI層中,創(chuàng)建了一個BpBinder對象,它的句柄值為0,它的地址保存在gBinderProxyOffsets.mObject中,因此,這里通過下面語句得到這個BpBinder對象的IBinder接口:最后,通過BpBinder::transact函數(shù)進入到Binder驅動程序,然后Binder驅動程序喚醒ServiceManager響應這個ADD_SERVICE_TRANSACTION請求:status_terr=target->transact(code,*data,reply,flags);需要注意的是,這里的data包含了一個JavaBBinderHolder類型的Binder實體對象,它就代表了我們上面創(chuàng)建的HelloService。ServiceManager收到這個ADD_SERVICE_TRANSACTION請求時,就會把這個Binder實體納入到自己內部進行管理。58Client獲取HelloService的Java遠程接口的過程在Hello這個Activity的onCreate函數(shù),通過IServiceManager.getService函數(shù)來獲得HelloService的遠程接口:59ServiceManager.getServiceServiceManager.getService的實現(xiàn)實際上是調用了ServiceManagerProxy.getService函數(shù):

最終通過mRemote.transact來執(zhí)行實際操作。我們在前面已經(jīng)介紹過了,這里的mRemote實際上是一個BinderProxy對象,它的transact成員函數(shù)是一個JNI方法,實現(xiàn)在frameworks/base/core/jni/android_util_Binder.cpp文件中的android_os_BinderProxy_transact函數(shù)中。60HelloService的引用status_t

err

=

target->transact(code,

*data,

reply,

flags);

這里的reply變量里面就包括了一個HelloService的引用了。注意,這里的reply變量就是我們在ServiceManagerProxy.getService函數(shù)里面?zhèn)鬟M來的參數(shù)reply,它是一個Parcel對象。readStrongBinder它也是一個JNI方法,實現(xiàn)在frameworks/base/core/jni/android_util_Binder.cpp文件中:這里首先把Java語言實現(xiàn)的Parcel對象class轉換成C++語言實現(xiàn)的Parcel對象parcel,接著,通過parcel->readStrongBinder函數(shù)來獲得一個Binder引用。62javaObjectForIBinder此時return

javaObjectForIBinder(env,

parcel->readStrongBinder());

相當于return

javaObjectForIBinder(env,

new

BpBinder(handle));

這里的handle就是HelloService這個Binder實體在Client進程中的句柄了,它是由Binder驅動程序設置的,上層不用關心它的值具體是多少。至于javaObjectForIBinder這個函數(shù),它的作用就是創(chuàng)建一個BinderProxy對象,并且把剛才獲得的BpBinder對象的地址保存在這個BinderProxy對象的mObject成員變量中。返回到Hello.onCreate函數(shù)helloService

=

IHelloService.Stub.asInterface(

ServiceManager.getService(“hello”));

相當于helloService

=

IHelloService.Stub.asInterface(new

BinderProxy()));

IHelloService.Stub.asInterface

這里的obj是一個BinderProxy對象,它的queryLocalInterface返回null,于是調用下面語句獲得HelloService的遠程接口:returnnewandroid.os.IHelloService.Stub.Proxy(obj);相當于

returnnewandroid.os.IHelloService.Stub.Proxy(newBinderProxy());這樣,我們就獲得了HelloService的遠程接口了,它實質上是一個實現(xiàn)了IHelloService接口的IHelloService.Stub.Proxy對象。65IHelloService.getVal函數(shù)在Hello::onClick函數(shù)中調用了IHelloService.getVal函數(shù):這里的helloService接口實際上是一個IHelloService.Stub.Proxy對象,因此,我們進入到IHelloService.Stub.Proxy類的getVal函數(shù)中:66IHelloService.Stub.Proxy類的getVal函數(shù)

這里我們可以看出,實際上是通過mRemote.transact來請求HelloService執(zhí)行TRANSACTION_getVal操作。這里的mRemote是一個BinderProxy對象,這是我們在前面獲取HelloService的Java遠程接口的過程中創(chuàng)建的。

BinderProxy.transact函數(shù)是一個JNI方法,最過調用到Binder驅動程序,Binder驅動程序喚醒HelloService這個Server。67JavaBBinder類的onTransactHelloService這個Server線程被喚醒之后,就會調用JavaBBinder類的onTransact函數(shù):

前面我們在介紹HelloService的啟動過程時,曾經(jīng)介紹過,JavaBBinder類里面的成員變量mObject就是HelloService類的一個實例對象了。因此,這里通過語句:jbooleanres=env->CallBooleanMethod(mObject,gBinderOffsets.mExecTransact,code,(int32_t)&data,(int32_t)reply,flags);就調用了HelloService.execTransact函數(shù),而HelloService.execTransact函數(shù)繼承了Binder類的execTransact函數(shù):68Binder類的execTransact函數(shù)

這里又調用了onTransact函數(shù)來作進一步處理。由于HelloService類繼承了IHelloService.Stub類,而IHelloService.Stub類實現(xiàn)了onTransact函數(shù),HelloService類沒有實現(xiàn),因此,最終調用了IHelloService.Stub.onTransact函數(shù):69IHelloService.Stub.onTransact函數(shù)

函數(shù)最終又調用了HelloService.getVal函數(shù):70HelloService.getVal函數(shù)

最終,經(jīng)過層層返回,就回到IHelloService.Stub.Proxy.getVal函數(shù)中來了,從下面語句返回:mRemote.transact(Stub.TRANSACTION_getVal,_data,_reply,0);

并將結果讀出來:_result=_reply.readInt();最后將這個結果返回到Hello.onClick函數(shù)中。Android應用程序啟動過程源碼剖析1,Android應用程序框架層創(chuàng)建的應用程序進程具有兩個特點,一是進程的入口函數(shù)是ActivityThread.main,二是進程天然支持Binder進程間通信機制;這兩個特點都是在進程的初始化過程中實現(xiàn)的;2,進程創(chuàng)建完成之后,Android應用程序框架層就會在這個進程中將ActivityThread類加載進來,然后執(zhí)行它的main函數(shù),這個main函數(shù)就是進程執(zhí)行消息循環(huán)的地方了;應用程序中Server實現(xiàn)疑問Binder通信時具有四個組件,分別是驅動程序、守護進程、Client以及Server,其中Server組件在初始化時必須進入一個循環(huán)中不斷地與Binder驅動程序進行到交互,以便獲得Client組件發(fā)送的請求,但是,當我們在Android應用程序中實現(xiàn)Server組件的時候,我們并沒有讓進程進入一個循環(huán)中去等待Client組件的請求,然而,當Client組件得到這個Server組件的遠程接口時,卻可以順利地和Server組件進行進程間通信,這就是因為Android應用程序進程在創(chuàng)建的時候就已經(jīng)啟動了一個線程池來支持Server組件和Binder驅動程序之間的交互了,這樣,極大地方便了在Android應用程序中創(chuàng)建Server組件。ActivityManagerService1,在Android應用程序框架層中,是由ActivityManagerService組件負責為Android應用程序創(chuàng)建新的進程的,它本來也是運行在一個獨立的進程之中,不過這個進程是在系統(tǒng)啟動的過程中創(chuàng)建的。ActivityManagerService組件一般會在什么情況下會為應用程序創(chuàng)建一個新的進程呢?當系統(tǒng)決定要在一個新的進程中啟動一個Activity或者Service時,它就會創(chuàng)建一個新的進程了,然后在這個新的進程中啟動這個Activity或者Service;2,ActivityManagerService啟動新的進程是從其成員函數(shù)startProcessLocked開始的;Android進程創(chuàng)建時序圖ActivityManagerService.startProcessLocked1,這個函數(shù)定義在/android/server/am/ActivityManagerService.java文件中;2,它調用了Process.start函數(shù)開始為應用程序創(chuàng)建新的進程,注意,它傳入一個第一個參數(shù)為“android.app.ActivityThread”,這就是進程初始化時要加載的Java類了,把這個類加載到進程之后,就會把它里面的靜態(tài)成員函數(shù)main作為進程的入口點,后面我們會看到;76Process.start

1,這個函數(shù)定義在frameworks/base/core/java/android/os/Process.java文件中;2,這里的supportsProcesses函數(shù)返回值為true,它是一個Native函數(shù),實現(xiàn)在frameworks/base/core/jni/android_util_Process.cpp文件中;77supportsProcessesjbooleanandroid_os_Process_supportsProcesses(JNIEnv*env,jobjectclazz){returnProcessState::self()->supportsProcesses();}ProcessState::supportsProcesses函數(shù)定義在frameworks/base/libs/binder/ProcessState.cpp文件中:boolProcessState::supportsProcesses()const{returnmDriverFD>=0;}設備文件/dev/bindermDriverFD是設備文件/dev/binder的打開描述符,如果成功打開了這個設備文件,那么它的值就會大于等于0,因此,它的返回值為true;回到Process.start函數(shù)中,它調用startViaZygote函數(shù)進一步操作;Process.startViaZygote1,這個函數(shù)定義在frameworks/base/core/java/android/os/Process.java文件中;2,這個函數(shù)將創(chuàng)建進程的參數(shù)放到argsForZygote列表中去,如參數(shù)“--runtime-init”表示要為新創(chuàng)建的進程初始化運行時庫,然后調用zygoteSendArgsAndGetPid函數(shù)進一步操作;80Process.zygoteSendArgsAndGetPid1,這個函數(shù)定義在frameworks/base/core/java/android/os/Process.java文件中;2,這里的sZygoteWriter是一個Socket寫入流,是由openZygoteSocketIfNeeded函數(shù)打開的:81openZygoteSocketIfNeeded這個Socket由/android/internal/os/ZygoteInit.java文件中的ZygoteInit類在runSelectLoopMode函數(shù)偵聽的;82ZygoteInit.runSelectLoopMode1,這個函數(shù)定義在/android/internal/os/ZygoteInit.java文件中;2,

當Step4將數(shù)據(jù)通過Socket接口發(fā)送出去后,就會下面這個語句:done=peers.get(index).runOnce();

這里從peers.get(index)得到的是一個ZygoteConnection對象,表示一個Socket連接,因此,接下來就是調用ZygoteConnection.runOnce函數(shù)進一步處理了;83ZygoteConnection.runOnce1,這個函數(shù)定義在/android/internal/os/ZygoteConnection.java文件中;2,真正創(chuàng)建進程的地方就是在這里了:if(pid==0){ //inchild handleChildProc(parsedArgs,descriptors,newStderr); //shouldneverhappen returntrue;}else{/*pid!=0*/ ......}84ZygoteConnection.handleChildProc1,這個函數(shù)定義在/android/internal/os/ZygoteConnection.java文件中;2,

由于在前面指定了"--runtime-init"參數(shù),表示要為新創(chuàng)建的進程初始化運行時庫,因此,這里的parseArgs.runtimeInit值為true,于是就繼續(xù)執(zhí)行RuntimeInit.zygoteInit進一步處理了。85

RuntimeInit.zygoteInit1,這個函數(shù)定義在/android/internal/os/RuntimeInit.java文件中;2,

這里有兩個關鍵的函數(shù)調用,一個是zygoteInitNative函數(shù)調用,一個是invokeStaticMain函數(shù)調用,前者就是執(zhí)行Binder驅動程序初始化的相關工作了,正是由于執(zhí)行了這個工作,才使得進程中的Binder對象能夠順利地進行Binder進程間通信,而后一個函數(shù)調用,就是執(zhí)行進程的入口函數(shù),這里就是執(zhí)行startClass類的main函數(shù)了,而這個startClass即是我們前面?zhèn)鬟M來的“android.app.ActivityThread”值,表示要執(zhí)行android.app.ActivityThread類的main函數(shù);86RuntimeInit.zygoteInitNative1,這個函數(shù)定義在/android/internal/os/RuntimeInit.java文件中;2,這里可以看出,函數(shù)zygoteInitNative是一個Native函數(shù),實現(xiàn)在frameworks/base/core/jni/AndroidRuntime.cpp文件中:staticvoidcom_android_internal_os_RuntimeInit_zygoteInit(JNIEnv*env,jobjectclazz){gCurRuntime->onZygoteInit();}87AndroidRuntime1,前面調用了全局變量gCurRuntime的onZygoteInit函數(shù),這個全局變量的定義在frameworks/base/core/jni/AndroidRuntime.cpp文件開頭的地方:staticAndroidRuntime*gCurRuntime=NULL;2,

這里可以看出,它的類型為AndroidRuntime,它是在AndroidRuntime類的構造函數(shù)中初始化的,AndroidRuntime類的構造函數(shù)也是定義在frameworks/base/core/jni/AndroidRuntime.cpp文件中:AndroidRuntime::AndroidRuntime(){......assert(gCurRuntime==NULL);//oneperprocessgCurRuntime=this;}AndroidRuntime與AppRuntime1,么這個AndroidRuntime類的構造函數(shù)又是什么時候被調用的呢?AndroidRuntime類的聲明在frameworks/base/include/android_runtime/AndroidRuntime.h文件中,如果我們打開這個文件會看到,它是一個虛擬類,也就是我們不能直接創(chuàng)建一個AndroidRuntime對象,只能用一個AndroidRuntime類的指針來指向它的某一個子類,這個子類就是AppRuntime了,它定義在frameworks/base/cmds/app_process/app_main.cpp文件中:intmain(intargc,constchar*constargv[]){ ...... AppRuntimeruntime;

......}實際是執(zhí)行了AppRuntime類的onZygoteInit1,AppRuntime類繼續(xù)了AndroidRuntime類,它也是定義在frameworks/base/cmds/app_process/app_main.cpp文件中:classAppRuntime:publicAndroidRuntime{ ......};2,

因此,在前面的com_android_internal_os_RuntimeInit_zygoteInit函數(shù),實際是執(zhí)行了AppRuntime類的onZygoteInit函數(shù);AppRuntime.onZygoteInit1,這個函數(shù)定義在frameworks/base/cmds/app_process/app_main.cpp文件中;2,這里它就是調用ProcessState::startThreadPool啟動線程池了,這個線程池中的線程就是用來和Binder驅動程序進行交互的了;91ProcessState.startThreadPool1,這個函數(shù)定義在frameworks/base/libs/binder/ProcessState.cpp文件中;2,ProcessState類是Binder進程間通信機制的一個基礎組件,這里它調用spawnPooledThread函數(shù)進一步處理;92ProcessState.spawnPooledThread1,這個函數(shù)定義在frameworks/base/libs/binder/ProcessState.cpp文件中;2,這里它會創(chuàng)建一個Poo

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論