原文鏈接:Android系統(tǒng)服務(wù)(SystemService)簡介 - CSDN博客
什么是SystemService
我們在Android開發(fā)過程中經(jīng)常會用到各種各樣的系統(tǒng)管理服務(wù)巴粪,如進(jìn)行窗口相關(guān)的操作會用到窗口管理服務(wù)WindowManager创淡,進(jìn)行電源相關(guān)的操作會用到電源管理服務(wù)PowerManager辣垒,還有很多其他的系統(tǒng)管理服務(wù)刁品,如通知管理服務(wù)NotifacationManager、振動管理服務(wù)Vibrator合住、電池管理服務(wù)BatteryManager…… 這些Manager提供了很多對系統(tǒng)層的控制接口绰精。對于App開發(fā)者撒璧,只需要了解這些接口的使用方式就可以方便的進(jìn)行系統(tǒng)控制透葛,獲得系統(tǒng)各個服務(wù)的信息,而不需要了解這些接口的具體實現(xiàn)方式卿樱。而對于Framework開發(fā)者僚害,則需要了解這些Manager服務(wù)的常用實現(xiàn)模式,維護(hù)這些Manager的接口,擴(kuò)展這些接口萨蚕,或者實現(xiàn)新的Manager靶草。?
一個簡單的SystemService
我們從一個簡單的系統(tǒng)服務(wù)Vibrator服務(wù)來看一下一個系統(tǒng)服務(wù)是怎樣建立的。?
Vibrator服務(wù)提供的控制手機(jī)振動的接口岳遥,應(yīng)用可以調(diào)用Vibrator的接口來讓手機(jī)產(chǎn)生振動奕翔,達(dá)到提醒用戶的目的。?
從Android的官方文檔中可以看到Vibrator只是一個抽象類浩蓉,只有4個抽象接口:
abstract void cancel()?取消振動
abstract boolean hasVibrator()?是否有振動功能
abstract void vibrate(long[] pattern, int repeat)?按節(jié)奏重復(fù)振動
abstract void vibrate(long milliseconds)?持續(xù)振動
應(yīng)用中使用振動服務(wù)的方法也很簡單派继,如讓手機(jī)持續(xù)振動500毫秒:
Vibrator mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mVibrator.vibrate(500);
Vibrator使用起來很簡單,我們再來看一下實現(xiàn)起來是不是也簡單捻艳。?
從文檔中可以看到Vibrator只是定義在android.os?包里的一個抽象類驾窟,在源碼里的位置即frameworks/base/core/java/android/os/Vibrator.java,那么應(yīng)用中實際使用的是哪個實例呢认轨?應(yīng)用中使用的Vibrator實例是通過Context的一個方法getSystemService(Context.VIBRATOR_SERVICE)獲得的绅络,而Context的實現(xiàn)一般都在ContextImpl中,那我們就看一下ContextImpl是怎么實現(xiàn)getSystemService的:?
frameworks/base/core/java/android/app/ContextImpl.java
@Override
public Object getSystemService(String name) {
? ? return SystemServiceRegistry.getSystemService(this, name);
}
frameworks/base/core/java/android/app/SystemServiceRegistry.java?
(SystemServiceRegistry是 Android 6.0之后才有的嘁字,Android 6.0 之前的代碼沒有該類恩急,下面的代碼是直接寫在ContextImpl里的)
public static Object getSystemService(ContextImpl ctx, String name) {
? ? ServiceFetcher fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
? ? return fetcher != null ? fetcher.getService(ctx) : null;
}
SYSTEM_SERVICE_MAP是一個HashMap,通過我們服務(wù)的名字name字符串纪蜒,從這個HashMap里取出一個ServiceFetcher假栓,再return這個ServiceFetcher的getService()。ServiceFetcher是什么霍掺?它的getService()又是什么匾荆?既然他是從SYSTEM_SERVICE_MAP這個HashMap里get出來的,那就找一找這個HashMap都put了什么杆烁。?
通過搜索SystemServiceRegistry可以找到如下代碼:
private static void registerService(String serviceName, Class serviceClass,
? ? ? ? ServiceFetcher serviceFetcher) {
? ? SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
? ? SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}
這里往SYSTEM_SERVICE_MAP里put了一對String與ServiceFetcher組成的key/value對牙丽,registerService()又是從哪里調(diào)用的?繼續(xù)搜索可以發(fā)現(xiàn)很多類似下面的代碼:
static {
? ? registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
? ? ? ? ? ? new CachedServiceFetcher() {
? ? ? ? @Override? ? ? ??
????????public AccessibilityManager createService(ContextImpl ctx) {
? ? ? ? ? ? return AccessibilityManager.getInstance(ctx);
? ? ? ? }});
? ? ...
? ? registerService(Context.VIBRATOR_SERVICE, Vibrator.class,
? ? ? ? ? ? new CachedServiceFetcher() {
? ? ? ? @Override? ? ? ??
????????public Vibrator createService(ContextImpl ctx) {
? ? ? ? ? ? return new SystemVibrator(ctx);
? ? ? ? }});
? ? ...
}
SystemServiceRegistry的static代碼塊里通過registerService注冊了很多的系統(tǒng)服務(wù)兔魂,其中就包括我們正在調(diào)查的VIBRATOR_SERVICE烤芦,通過結(jié)合上面的分析代碼可以可以知道getSystemService(Context.VIBRATOR_SERVICE)得到的是一個SystemVibrator的實例,通過查看SystemVibrator的代碼也可以發(fā)現(xiàn)SystemVibrator確實是繼承自Vibrator:
public class SystemVibrator extends Vibrator {
?????...
}
我們再從SystemVibrator看一下系統(tǒng)的振動控制是怎么實現(xiàn)的析校。以hasVibrator()為例构罗,這個是查詢當(dāng)前系統(tǒng)是否能夠振動,在SystemVibrator中它的實現(xiàn)如下:
public boolean hasVibrator() {
? ? ...
? ? try {
? ? ? ? return mService.hasVibrator();
? ? } catch (RemoteException e) {
? ? }
? ? ...
}
這里直接調(diào)用了一個mService.hasVibrator()智玻。mService是什么遂唧?哪來的?搜索一下可以發(fā)現(xiàn):
private final IVibratorService mService;
public SystemVibrator() {
? ? ...
? ? mService = IVibratorService.Stub.asInterface(
? ? ? ? ? ? ServiceManager.getService("vibrator"));
}
mService?是一個IVibratorService吊奢,我們先不去管IVibratorService.Stub.asInterface是怎么回事盖彭,先看一下IVibratorService是什么。搜索一下代碼發(fā)現(xiàn)這并不是一個java文件,而是一個aidl文件:?
frameworks/base/core/java/android/os/IVibratorService.aidl?
AIDL (Android Interface Definition Language) 是Android中的接口定義文件召边,為系統(tǒng)提供了一種簡單跨進(jìn)程通信方法铺呵。?
IVibratorService?中定義了幾個接口,SystemVibrator中使用的也是這幾個接口隧熙,包括我們剛才使用的hasVibrator()
interface IVibratorService
{
? ? boolean hasVibrator();
? ? void vibrate(...);
? ? void vibratePattern(...);
? ? void cancelVibrate(IBinder token);
}
這里又只是接口定義片挂,接口實現(xiàn)在哪呢?通過在frameworks/base目錄下進(jìn)行g(shù)rep搜索贞盯,或者在AndroidXRef搜索宴卖,可以發(fā)現(xiàn)IVibratorService接口的實現(xiàn)在frameworks/base/services/java/com/android/server/VibratorService.java
public class VibratorService extends IVibratorService.Stub
可以看到?VibratorService實現(xiàn)了IVibratorService定義的所有接口,并通過JNI調(diào)用到native層邻悬,進(jìn)行更底層的實現(xiàn)症昏。更底層的實現(xiàn)不是這篇文檔討論的內(nèi)容,我們需要分析的是VibratorService怎么成為系統(tǒng)服務(wù)的父丰。那么VibratorService是怎么注冊為系統(tǒng)服務(wù)的呢肝谭?在SystemServer里面:
VibratorService vibrator = null;
...
//實例化VibratorService并添加到ServiceManager
traceBeginAndSlog("StartVibratorService");
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
...
//通知服務(wù)系統(tǒng)啟動完成
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeVibratorServiceReady");
try {
? ? vibrator.systemReady();
} catch (Throwable e) {
? ? reportWtf("making Vibrator Service ready", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
這樣在SystemVibrator里就可以通過下面的代碼連接到VibratorService,與底層的系統(tǒng)服務(wù)進(jìn)行通信了:
IVibratorService.Stub.asInterface(ServiceManager.getService("vibrator"));
mService相當(dāng)于IVibratorService在應(yīng)用層的一個代理蛾扇,所有的實現(xiàn)還是在SystemServer的VibratorService里攘烛。?
看代碼時可以發(fā)現(xiàn)registerService是在static代碼塊里靜態(tài)調(diào)用的,所以getSystemService獲得的各個Manager也都是單例的镀首。
System Service實現(xiàn)流程
從上面的分析坟漱,我們可以總結(jié)出Vibrator服務(wù)的整個實現(xiàn)流程:
1. 定義一個抽象類Vibrator,定義了應(yīng)用中可以訪問的一些抽象方法?
frameworks/base/core/java/android/os/Vibrator.java
2. 定義具體的類SystemVibrator繼承Vibrator更哄,實現(xiàn)抽象方法?
frameworks/base/core/java/android/os/SystemVibrator.java
3. 定義一個AIDL接口文件IVibratorService芋齿,定義系統(tǒng)服務(wù)接口?
frameworks/base/core/java/android/os/IVibratorService.aidl
4. 定義服務(wù)VibratorService,實現(xiàn)IVibratorService定義的接口?
frameworks/base/services/java/com/android/server/VibratorService.java
public class Vibrator Service extends IVibratorService.Stub
5.將VibratorServicey添加到系統(tǒng)服務(wù)?
frameworks/base/services/java/com/android/server/SystemServer.java
VibratorService vibrator = null;
...
//實例化VibratorService并添加到ServiceManager
Slog.i(TAG, "Vibrator Service");
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
...
//通知服務(wù)系統(tǒng)啟動完成
try {
? ? vibrator.systemReady();
} catch (Throwable e) {
? ? reportWtf("making Vibrator Service ready", e);
}
6. 在SystemVibrator中通過IVibratorService的代理連接到VibratorService成翩,這樣SystemVibrator的接口實現(xiàn)里就可以調(diào)用IVibratorService的接口:?
frameworks/base/core/java/android/os/SystemVibrator.java
private final IVibratorService mService;
...
public SystemVibrator() {
? ? ...
? ? mService = IVibratorService.Stub.asInterface(
? ? ? ? ? ? ServiceManager.getService("vibrator"));
? ? ...
? ? public boolean hasVibrator() {
? ? ? ? ...
? ? ? ? try {
? ? ? ? ? ? return mService.hasVibrator();
? ? ? ? } catch (RemoteException e) {
? ? ? ? }
? ? ? ? ...
? ? }
}
7. 在Context里定義一個代表Vibrator服務(wù)的字符串?
frameworks/base/core/java/android/content/Context.java
public static final String VIBRATOR_SERVICE = "vibrator";
8. 在ContextImpl里添加SystemVibrator的實例化過程?
frameworks/base/core/java/android/app/ContextImpl.java
registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
? ? return new SystemVibrator(ctx);
}});?
9. 在應(yīng)用中使用Vibrator的接口
Vibrator mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mVibrator.vibrate(500);
10. 為保證編譯正常觅捆,還需要將AIDL文件添加到編譯配置里?
frameworks/base/Android.mk
LOCAL_SRC_FILES += \
...
core/java/android/os/IVibratorService.aidl \
System Service 新加接口
如果我們需要實現(xiàn)一個新的系統(tǒng)服務(wù),就可以按照上面的步驟在系統(tǒng)中擴(kuò)展出一個新的服務(wù)麻敌,并給應(yīng)用層提供出使用接口栅炒。如果想在Vibrator里添加一個新的接口,需要下面3步:
1. 在IVibratorService添加接口术羔;
2. 在VibratorService添加接口的實現(xiàn)赢赊;
3. 在Vibrator及SystemVibrator里擴(kuò)展新的接口;
這樣應(yīng)用中就可以使用Vibrator的新接口了级历。
應(yīng)用層與 System Service 通信
????上面的實現(xiàn)我們看到的只是從應(yīng)用層通過服務(wù)代理释移,調(diào)用系統(tǒng)服務(wù)的接口,如果我們想反過來鱼喉,將系統(tǒng)服務(wù)的狀態(tài)通知給應(yīng)用層秀鞭,該怎么做呢?
方法一:使用Broadcast
????我們知道使用Broadcast廣播可以實現(xiàn)跨進(jìn)程的消息傳遞扛禽,一些系統(tǒng)服務(wù)也使用了這種方法锋边。如電池管理服務(wù)BatteryManagerService,收到底層上報的電池狀態(tài)變化信息時编曼,就將當(dāng)前的電池狀態(tài)封裝在一個Intent里豆巨,action為android.intent.action.BATTERY_CHANGED。應(yīng)用只要注冊一個對應(yīng)的BroadcastReceiver就可以收到BatterManagerService發(fā)送的電池狀態(tài)信息掐场。
方法二:使用AIDL?
????從上面我們可以知道往扔,通過AIDL定義一套接口,由系統(tǒng)服務(wù)端實現(xiàn)這些接口熊户,應(yīng)用端使用一個相應(yīng)的代理就可以訪問系統(tǒng)服務(wù)的接口萍膛,那反過來讓應(yīng)用端實現(xiàn)AIDL接口,系統(tǒng)服務(wù)端使用代理調(diào)用應(yīng)用端的接口可不可以呢嚷堡?答案是YES蝗罗。那么接下來的問題是怎么讓系統(tǒng)服務(wù)得到這個代理。我們再來看一個LocationManager的例子蝌戒。
LocationManager是系統(tǒng)的定位服務(wù)串塑,應(yīng)用通過LocationManager可以獲得設(shè)備當(dāng)前的地理位置信息。下面是LocationManager的使用代碼片段:
//獲得定位服務(wù)
LocationManager locationManager =
? ? ? ? (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//定義定位監(jiān)聽器
LocationListener locationListener = new LocationListener() {
? ? public void onLocationChanged(Location location) {
? ? ? ? //監(jiān)聽到位置信息
? ? }
? ? ...
};
//注冊監(jiān)聽器
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
? ? ? ? 0, 0, locationListener);
從上面的代碼可以看到北苟,我們創(chuàng)建了一個位置監(jiān)聽器LocationListener桩匪,并將這個監(jiān)聽器在LocationManager里進(jìn)行了注冊。當(dāng)系統(tǒng)定位到系統(tǒng)的位置后友鼻,就會回調(diào)監(jiān)聽器的onLocationChanged()傻昙,將位置信息通知給監(jiān)聽器。LocationListener就是一個系統(tǒng)服務(wù)調(diào)用應(yīng)用層接口的例子彩扔,我們就研究一下LocationListener的實現(xiàn)方式屋匕。?
我們先從LocationManager怎么注冊LocationListener開始研究:?
frameworks/base/location/java/android/location/LocationManager.java
private final ILocationManager mService;
...
private void requestLocationUpdates(LocationRequest request,
? ? ? ? LocationListener listener, Looper looper, PendingIntent intent) {
? ? ...
? ? // wrap the listener class
? ? ListenerTransport transport = wrapListener(listener, looper);
? ? try {
? ? ? ? mService.requestLocationUpdates(request, transport,
? ? ? ? ? ? ? ? intent, packageName);
? } catch (RemoteException e) {
? ? ? Log.e(TAG, "RemoteException", e);
? }
}
可以看到LocationListener被重新封裝成了一個ListenerTransport,然后傳遞給了ILocationManager?借杰,從前面的分析可以猜測到這個ILocationManager應(yīng)該就是LocationManagerService的一個代理过吻。那么ListenerTransport又是什么呢?搜索LocationManager.java可以找到:
private class ListenerTransport extends ILocationListener.Stub {
?...
? ? @Override
? ? public void onLocationChanged(Location location) {
? ? ? ? ...
? ? }
}
原來是ILocationListener.Stub的一個繼承實現(xiàn)蔗衡,那么ILocationListener應(yīng)該就是一個AIDL接口定義:?
frameworks/base/location/java/android/location/ILocationListener.aidl
oneway interface ILocationListener
{
? ? void onLocationChanged(in Location location);
? ? ...
}
而在LocationManagerService里只要調(diào)用ILocationListener的方法就可以將消息傳遞給應(yīng)用層的監(jiān)聽:
mListener.onLocationChanged(new Location(location));
實現(xiàn) System Service 的注意事項
1. 注意防止阻塞?
應(yīng)用層訪問系統(tǒng)服務(wù)提供的接口時會有兩種情況:
一種是應(yīng)用調(diào)用端需要等待服務(wù)實現(xiàn)端處理完成纤虽,返回處理結(jié)果,這樣如果服務(wù)端發(fā)生阻塞绞惦,那么應(yīng)用端也會發(fā)生阻塞逼纸,因此在實現(xiàn)服務(wù)端的實現(xiàn)時要注意不要發(fā)生阻塞。
另一種是調(diào)用端不需要等待服務(wù)端返回結(jié)果济蝉,調(diào)用完成后直接返回void杰刽,這樣服務(wù)端發(fā)生阻塞不會影響到應(yīng)用端菠发,這樣的單向的接口在AIDL里定義時需要添加oneway關(guān)鍵字,如:
oneway void statusBarVisibilityChanged(int visibility);
對于需要在服務(wù)端調(diào)用贺嫂,在應(yīng)用端實現(xiàn)的接口滓鸠,考慮到系統(tǒng)的穩(wěn)定性以及安全性,一般都會設(shè)計成上面的第二種第喳,即AIDL里所有的接口都是單向的糜俗,如上面的ILocationListener
oneway interface ILocationListener
2. 注意多線程訪問?
每個系統(tǒng)服務(wù)在系統(tǒng)進(jìn)程中只有一個實例,而且應(yīng)用中系統(tǒng)服務(wù)的代理也是單例的曲饱,而且應(yīng)用端的訪問悠抹,在系統(tǒng)進(jìn)程都是使用獨(dú)立的線程進(jìn)行響應(yīng),所以訪問同一個系統(tǒng)服務(wù)的接口時必然會出現(xiàn)多個線程或者多個進(jìn)程同時訪問的情況扩淀。為保證系統(tǒng)服務(wù)的線程安全楔敌,需要對系統(tǒng)服務(wù)的進(jìn)程進(jìn)行多線程訪問的保護(hù),目前主要有兩種實現(xiàn)線程安全的方法:
一種是通過同步鎖機(jī)制驻谆,鎖住一個對象實例(一般是這個服務(wù)對象本身)梁丘,這樣這個服務(wù)同一時間只能響應(yīng)一個訪問請求,如LocationManagerService里:
public boolean callStatusChangedLocked(...) {
? ? ...
? ? synchronized (this) {
? ? ...
? ? }
}
另一種方法就是使用Handler機(jī)制旺韭,這種服務(wù)一般會創(chuàng)建一個單獨(dú)的線程氛谜,當(dāng)有應(yīng)用端訪問請求到來時會向服務(wù)線程的Handler里發(fā)送一個Message,利用單線程順序執(zhí)行的特性区端,保證所有的訪問都按順序進(jìn)行處理值漫,但這種方法只適合單向的訪問,不適合需要返回的雙向訪問织盼。
ServiceManager原理
從上面流程的分析我們可以看到杨何,所有的系統(tǒng)服務(wù)最終都是由ServiceManager來管理的,那么ServiceManager是怎么管理這些系統(tǒng)服務(wù)的呢沥邻?還是先看上面的VibratorService的實現(xiàn):?
VibratorService通過addService()將自己注冊到ServiceManager里危虱,SystemVibrator通過getService()獲得一個服務(wù)代理,并與服務(wù)進(jìn)行通信交互唐全,那么ServiceManager又是什么埃跷?它是怎么管理服務(wù)的注冊與代理的呢?我們先從addService()與getService()開始邮利,分析一下ServiceManager:?
frameworks/base/core/java/android/os/ServiceManager.java
public final classServiceManager{
?public static void addService(String name, IBinder service) {
? ? ? ? ...
? ? ? ? getIServiceManager().addService(name, service, false);
? ? }
? ? public static IBinder getService(String name) {
? ? ? ? ...
? ? ? ? return getIServiceManager().getService(name);
? ? }
}
addService()和getService()都是直接調(diào)用了getIServiceManager()的方法弥雹,getIServiceManager()返回的又是什么呢?
private static IServiceManager getIServiceManager() {
? ? if (sServiceManager != null) {
? ? ? ? return sServiceManager;
? ? }
? ? // Find the service manager
? ? sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
? ? return sServiceManager;
}
這里是創(chuàng)建了一個IServiceManager類型的單實例延届,具體的實例又是通過ServiceManagerNative創(chuàng)建的:
ServiceManagerNative.asInterface(BinderInternal.getContextObject());
先來看BinderInternal.getContextObject()?
frameworks/base/core/java/com/android/internal/os/BinderInternal.java
public static final native IBinder getContextObject();
getContextObject()是在native層實現(xiàn)的?
frameworks/base/core/jni/android_util_Binder.cpp
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env,
? ? ? ? jobject clazz)
{
? ? sp b = ProcessState::self()->getContextObject(NULL);
? ? return javaObjectForIBinder(env, b);
}
后面的實現(xiàn)過程邏輯比較復(fù)雜剪勿,這里就不詳細(xì)分析了,只是說明一下大致流程方庭,感興趣的可以自己詳細(xì)研究一下binder的實現(xiàn)機(jī)制厕吉。?
ProcessState從名字可以看出這應(yīng)該是一個保存進(jìn)程狀態(tài)的類酱固,最好應(yīng)該用單實例的對象保存,所以ProcessState::self()得到的也就是ProcessState的一個單實例對象头朱,它的getContextObject()會繼續(xù)調(diào)用getStrongProxyForHandle(int32_t handle)返回一個IBinder?
frameworks/native/libs/binder/ProcessState.cpp
sp<IBinder>?ProcessState::getContextObject(const sp& caller)
{
? ? return getStrongProxyForHandle(0);
}
在getStrongProxyForHandle()中會根據(jù)傳入的參數(shù)handle創(chuàng)建一個BpBinder运悲,這個BpBinder會保存在一個數(shù)組mHandleToObject中,下次再用同樣的handle請求時不會再重新創(chuàng)建髓窜。由于我們傳入的handle=0扇苞,這里創(chuàng)建的BpBinder也就相當(dāng)于第0號BpBinder欺殿。?
之后的javaObjectForIBinder()會將C++的BpBinder對象封裝成Java的BinderProxy對象并返回寄纵。所以BinderInternal.getContextObject()得到的是一個BinderProxy對象,并關(guān)聯(lián)了native層的第0號BpBinder脖苏。
ServiceManagerNative.asInterface(BinderInternal.getContextObject());
相當(dāng)于
ServiceManagerNative.asInterface(new BinderProxy());
ServiceManagerNative.asInterface()又做了些什么呢程拭??
frameworks/base/core/java/android/os/ServiceManagerNative.java
static public IServiceManager asInterface(IBinder obj)
{
? ? ...? ?
? ? return new ServiceManagerProxy(obj);
}
這里會將BinderProxy再封裝成一個ServiceManagerProxy(),所以getIServiceManager()得到的其實是一個ServiceManagerProxy棍潘,但是底層指向的是一個BpBinder(0)恃鞋。?
ServiceManagerProxy、BinderProxy以及BpBinder都是代理模式中的proxy端亦歉,真正的實現(xiàn)應(yīng)該在對應(yīng)的native端恤浪。我們接著看。?
addService()和getService()在代理端的實現(xiàn)應(yīng)該是在ServiceManagerProxy()里:
public IBinder getService(String name) throws RemoteException {
? ? Parcel data = Parcel.obtain();
? ? Parcel reply = Parcel.obtain();
? ? data.writeInterfaceToken(IServiceManager.descriptor);
? ? data.writeString(name);
? ? mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
? ? IBinder binder = reply.readStrongBinder();
? ? reply.recycle();
? ? data.recycle();
? ? return binder;
}
...
public void addService(String name, IBinder service, boolean allowIsolated)
? ? ? ? throws RemoteException {
? ? Parcel data = Parcel.obtain();
? ? Parcel reply = Parcel.obtain();
? ? data.writeInterfaceToken(IServiceManager.descriptor);
? ? data.writeString(name);
? ? data.writeStrongBinder(service);
? ? data.writeInt(allowIsolated ? 1 : 0);
? ? mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
? ? reply.recycle();
? ? data.recycle();
}
從上面兩個方法的實現(xiàn)可以看到肴楷,首先是創(chuàng)建了兩個可序列化的Parcel?data水由、reply,傳入的參數(shù)被放到了data里赛蔫,data砂客、reply又一起傳給了mRemote.transact(),之后又從reply里讀取結(jié)果呵恢。addService()的實現(xiàn)里還通過data.writeStrongBinder(service)寫入了一個IBinder的實例鞠值。同時注意到getService()和addService()里面調(diào)用mRemote.transact()傳遞的第一個參數(shù)分別為GET_SERVICE_TRANSACTION?和?ADD_SERVICE_TRANSACTION?,我們可以在IServiceManager里看到這是兩個int值渗钉,分別為1和3?
frameworks/base/core/java/android/os/IServiceManager.java
int GET_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION; //值為1
int CHECK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+1;
int ADD_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+2;
mRemote就是BinderProxy彤恶,真正的實現(xiàn)是C++里的BpBinder?
frameworks/native/libs/binder/BpBinder.cpp
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;
}
IPCThreadState里的transact會將proxy端的請求通過binder機(jī)制寫入到一塊共享內(nèi)存里,然后會有一個native端從共享內(nèi)存里讀出請求鳄橘,并執(zhí)行相應(yīng)的操作粤剧。那么這個native端在哪里呢?是不是ServiceManagerNative呢挥唠?但是ServiceManagerNative只是一個抽象類抵恋,我們并沒有找到繼承自它的子類。實際上ServiceManagerNative只是架構(gòu)方面的一個抽象定義宝磨,并沒有真正的一個實現(xiàn)弧关,真正實現(xiàn)ServiceManager?的native端功能的是在native層的service_manager.c中盅安。?
servicemanager是底層的一個獨(dú)立進(jìn)程,主要的實現(xiàn)代碼就在service_manager.c中世囊。?
frameworks/native/cmds/servicemanager/binder.h
enum {
? ? /* Must match definitions in IBinder.h and IServiceManager.h */
? ? PING_TRANSACTION? = B_PACK_CHARS('_','P','N','G'),
? ? SVC_MGR_GET_SERVICE = 1,
? ? SVC_MGR_CHECK_SERVICE,
? ? SVC_MGR_ADD_SERVICE,
? ? SVC_MGR_LIST_SERVICES,
};
frameworks/native/cmds/servicemanager/service_manager.c
#include "binder.h"
...
int svcmgr_handler(struct binder_state *bs,
? ? ? ? ? ? ? ? ? struct binder_transaction_data *txn,
? ? ? ? ? ? ? ? ? struct binder_io *msg,
? ? ? ? ? ? ? ? ? struct binder_io *reply)
{
? ? ...
? ? switch(txn->code) {
? ? case SVC_MGR_GET_SERVICE:
? ? case SVC_MGR_CHECK_SERVICE:
? ? ? ? s = bio_get_string16(msg, &len);
? ? ? ? if (s == NULL) {
? ? ? ? ? ? return -1;
? ? ? ? }
? ? ? ? handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid);
? ? ? ? if (!handle)
? ? ? ? ? ? break;
? ? ? ? bio_put_ref(reply, handle);
? ? ? ? return 0;
? ? case SVC_MGR_ADD_SERVICE:
? ? ? ? s = bio_get_string16(msg, &len);
? ? ? ? if (s == NULL) {
? ? ? ? ? ? return -1;
? ? ? ? }
? ? ? ? handle = bio_get_ref(msg);
? ? ? ? allow_isolated = bio_get_uint32(msg) ? 1 : 0;
? ? ? ? if (do_add_service(bs, s, len, handle, txn->sender_euid,
? ? ? ? ? ? allow_isolated, txn->sender_pid))
? ? ? ? ? ? return -1;
? ? ? ? break;
? ? ? ? ...
? ? }
}
service_manager.c的svcmgr_handler函數(shù)就是監(jiān)聽代理端請求命令的txn->code就是mRemote.transact()里傳過來的第一個參數(shù)别瞭。SVC_MGR_GET_SERVICE和SVC_MGR_ADD_SERVICE是在頭文件binder.h里定義的,它們的值與IServiceManager.java里定義的一致株憾,也是1和3蝙寨。?
我們先看SVC_MGR_ADD_SERVICE的響應(yīng):
首先通過s = bio_get_string16(msg, &len)獲得了service的名稱,
然后通過handle = bio_get_ref(msg)獲得了一個handle嗤瞎,這個handle就是我們之前通過writeStrongBinder寫入的IBinder墙歪,
最后通過do_add_service()添加注冊service
do_add_service()的實現(xiàn)如下:
int do_add_service(struct binder_state *bs,
? ? ? ? ? ? ? ? ? const uint16_t *s, size_t len,
? ? ? ? ? ? ? ? ? uint32_t handle, uid_t uid, int allow_isolated,
? ? ? ? ? ? ? ? ? pid_t spid)
{
? ? struct svcinfo *si;
? ? si = find_svc(s, len);
? ? if (si) {
? ? ? ? if (si->handle) {
? ? ? ? ? ? ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n",
? ? ? ? ? ? ? ? str8(s, len), handle, uid);
? ? ? ? ? ? svcinfo_death(bs, si);
? ? ? ? }
? ? ? ? si->handle = handle;
? ? } else {
? ? ? ? si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
? ? ? ? si->handle = handle;
? ? ? ? si->len = len;
? ? ? ? memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
? ? ? ? si->name[len] = '\0';
? ? ? ? si->death.func = (void*) svcinfo_death;
? ? ? ? si->death.ptr = si;
? ? ? ? si->allow_isolated = allow_isolated;
? ? ? ? si->next = svclist;
? ? ? ? svclist = si;
? ? }
? ? ...
}
struct svcinfo *find_svc(const uint16_t *s16, size_t len)
{
? ? struct svcinfo *si;
? ? for (si = svclist; si; si = si->next) {
? ? ? ? if ((len == si->len) &&
? ? ? ? ? ? !memcmp(s16, si->name, len * sizeof(uint16_t))) {
? ? ? ? ? ? return si;
? ? ? ? }
? ? }
? ? return NULL;
}
首先聲明了一個struct svcinfo *si
通過find_svc(s, len)查找一下同樣名稱的service之前是不是注冊過,防止重復(fù)注冊贝奇。find_svc()的實現(xiàn)里可以看到是通過遍歷一個svclist鏈表來查重的虹菲,svclist鏈表就是用來保存所有注冊過的service的
如果確認(rèn)沒有重復(fù)注冊service,就重新構(gòu)造一個svcinfo添加到svclist鏈表的頭部掉瞳。
我們再看SVC_MGR_GET_SERVICE的響應(yīng)毕源,主要是通過do_find_service()查找到對應(yīng)的service,并通過bio_put_ref(reply, handle)將查找到的handle返回陕习。do_find_service()的實現(xiàn)主要也是通過find_svc()去svclist鏈表中查找
uint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid)
{
? ? struct svcinfo *si = find_svc(s, len);
? ? ...
? ? return si->handle;
}
通過上面的流程梳理我們最終了解到:
1. 每個System Service通過調(diào)用ServiceManager.addService()將自己的名字以及IBinder引用保存到servicemanager進(jìn)程的一個鏈表里
2. 每個使用該System Service的進(jìn)程通過調(diào)用ServiceManager.getService()從servicemanager進(jìn)程獲得該System Service對應(yīng)的IBinder霎褐,就可以與該System Service進(jìn)行通信了