小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Android系統(tǒng)服務(wù)(SystemService)簡(jiǎn)介

 jiffes 2019-01-28

什么是SystemService

我們?cè)贏ndroid開發(fā)過程中經(jīng)常會(huì)用到各種各樣的系統(tǒng)管理服務(wù),如進(jìn)行窗口相關(guān)的操作會(huì)用到窗口管理服務(wù)WindowManager,進(jìn)行電源相關(guān)的操作會(huì)用到電源管理服務(wù)PowerManager,還有很多其他的系統(tǒng)管理服務(wù),如通知管理服務(wù)NotifacationManager、振動(dòng)管理服務(wù)Vibrator、電池管理服務(wù)BatteryManager…… 這些Manager提供了很多對(duì)系統(tǒng)層的控制接口。對(duì)于App開發(fā)者,只需要了解這些接口的使用方式就可以方便的進(jìn)行系統(tǒng)控制,獲得系統(tǒng)各個(gè)服務(wù)的信息,而不需要了解這些接口的具體實(shí)現(xiàn)方式。而對(duì)于Framework開發(fā)者,則需要了解這些Manager服務(wù)的常用實(shí)現(xiàn)模式,維護(hù)這些Manager的接口,擴(kuò)展這些接口,或者實(shí)現(xiàn)新的Manager。

一個(gè)簡(jiǎn)單的SystemService

我們從一個(gè)簡(jiǎn)單的系統(tǒng)服務(wù)Vibrator服務(wù)來看一下一個(gè)系統(tǒng)服務(wù)是怎樣建立的。
Vibrator服務(wù)提供的控制手機(jī)振動(dòng)的接口,應(yīng)用可以調(diào)用Vibrator的接口來讓手機(jī)產(chǎn)生振動(dòng),達(dá)到提醒用戶的目的。
從Android的官方文檔中可以看到Vibrator只是一個(gè)抽象類,只有4個(gè)抽象接口:

  • abstract void cancel() 取消振動(dòng)
  • abstract boolean hasVibrator() 是否有振動(dòng)功能
  • abstract void vibrate(long[] pattern, int repeat) 按節(jié)奏重復(fù)振動(dòng)
  • abstract void vibrate(long milliseconds) 持續(xù)振動(dòng)

應(yīng)用中使用振動(dòng)服務(wù)的方法也很簡(jiǎn)單,如讓手機(jī)持續(xù)振動(dòng)500毫秒:

Vibrator mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mVibrator.vibrate(500);
  • 1
  • 2

Vibrator使用起來很簡(jiǎn)單,我們?cè)賮砜匆幌聦?shí)現(xiàn)起來是不是也簡(jiǎn)單。
從文檔中可以看到Vibrator只是定義在android.os 包里的一個(gè)抽象類,在源碼里的位置即frameworks/base/core/java/android/os/Vibrator.java,那么應(yīng)用中實(shí)際使用的是哪個(gè)實(shí)例呢?應(yīng)用中使用的Vibrator實(shí)例是通過Context的一個(gè)方法getSystemService(Context.VIBRATOR_SERVICE)獲得的,而Context的實(shí)現(xiàn)一般都在ContextImpl中,那我們就看一下ContextImpl是怎么實(shí)現(xiàn)getSystemService的:
frameworks/base/core/java/android/app/ContextImpl.java

@Override
public Object getSystemService(String name) {
    return SystemServiceRegistry.getSystemService(this, name);
}
  • 1
  • 2
  • 3
  • 4

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;
}
  • 1
  • 2
  • 3
  • 4

SYSTEM_SERVICE_MAP是一個(gè)HashMap,通過我們服務(wù)的名字name字符串,從這個(gè)HashMap里取出一個(gè)ServiceFetcher,再return這個(gè)ServiceFetchergetService()。ServiceFetcher是什么?它的getService()又是什么?既然他是從SYSTEM_SERVICE_MAP這個(gè)HashMapget出來的,那就找一找這個(gè)HashMapput了什么。
通過搜索SystemServiceRegistry可以找到如下代碼:

private static <T> void registerService(String serviceName, Class<T> serviceClass,
        ServiceFetcher<T> serviceFetcher) {
    SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
    SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}
  • 1
  • 2
  • 3
  • 4
  • 5

這里往SYSTEM_SERVICE_MAPput了一對(duì)StringServiceFetcher組成的key/value對(duì),registerService()又是從哪里調(diào)用的?繼續(xù)搜索可以發(fā)現(xiàn)很多類似下面的代碼:

static {
    registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
            new CachedServiceFetcher<AccessibilityManager>() {
        @Override
        public AccessibilityManager createService(ContextImpl ctx) {
            return AccessibilityManager.getInstance(ctx);
        }});

    ...
    registerService(Context.VIBRATOR_SERVICE, Vibrator.class,
            new CachedServiceFetcher<Vibrator>() {
        @Override
        public Vibrator createService(ContextImpl ctx) {
            return new SystemVibrator(ctx);
        }});
    ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

SystemServiceRegistrystatic代碼塊里通過registerService注冊(cè)了很多的系統(tǒng)服務(wù),其中就包括我們正在調(diào)查的VIBRATOR_SERVICE,通過結(jié)合上面的分析代碼可以可以知道getSystemService(Context.VIBRATOR_SERVICE)得到的是一個(gè)SystemVibrator的實(shí)例,通過查看SystemVibrator的代碼也可以發(fā)現(xiàn)SystemVibrator確實(shí)是繼承自Vibrator

public class SystemVibrator extends Vibrator {
    ...
}
  • 1
  • 2
  • 3

我們?cè)購(gòu)?code>SystemVibrator看一下系統(tǒng)的振動(dòng)控制是怎么實(shí)現(xiàn)的。以hasVibrator()為例,這個(gè)是查詢當(dāng)前系統(tǒng)是否能夠振動(dòng),在SystemVibrator中它的實(shí)現(xiàn)如下:

public boolean hasVibrator() {
    ...
    try {
        return mService.hasVibrator();
    } catch (RemoteException e) {
    }
    ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

這里直接調(diào)用了一個(gè)mService.hasVibrator()。mService是什么?哪來的?搜索一下可以發(fā)現(xiàn):

private final IVibratorService mService;
public SystemVibrator() {
    ...
    mService = IVibratorService.Stub.asInterface(
            ServiceManager.getService("vibrator"));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

mService 是一個(gè)IVibratorService,我們先不去管IVibratorService.Stub.asInterface是怎么回事,先看一下IVibratorService是什么。搜索一下代碼發(fā)現(xiàn)這并不是一個(gè)java文件,而是一個(gè)aidl文件:
frameworks/base/core/java/android/os/IVibratorService.aidl
AIDL (Android Interface Definition Language) 是Android中的接口定義文件,為系統(tǒng)提供了一種簡(jiǎn)單跨進(jìn)程通信方法。
IVibratorService 中定義了幾個(gè)接口,SystemVibrator中使用的也是這幾個(gè)接口,包括我們剛才使用的hasVibrator()

interface IVibratorService
{
    boolean hasVibrator();
    void vibrate(...);
    void vibratePattern(...);
    void cancelVibrate(IBinder token);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

這里又只是接口定義,接口實(shí)現(xiàn)在哪呢?通過在frameworks/base目錄下進(jìn)行g(shù)rep搜索,或者在AndroidXRef搜索,可以發(fā)現(xiàn)IVibratorService接口的實(shí)現(xiàn)在frameworks/base/services/java/com/android/server/VibratorService.java

public class VibratorService extends IVibratorService.Stub
  • 1
  • 2

可以看到 VibratorService實(shí)現(xiàn)了IVibratorService定義的所有接口,并通過JNI調(diào)用到native層,進(jìn)行更底層的實(shí)現(xiàn)。更底層的實(shí)現(xiàn)不是這篇文檔討論的內(nèi)容,我們需要分析的是VibratorService怎么成為系統(tǒng)服務(wù)的。那么VibratorService是怎么注冊(cè)為系統(tǒng)服務(wù)的呢?在SystemServer里面:

VibratorService vibrator = null;
...
//實(shí)例化VibratorService并添加到ServiceManager
traceBeginAndSlog("StartVibratorService");
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
...
//通知服務(wù)系統(tǒng)啟動(dò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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

這樣在SystemVibrator里就可以通過下面的代碼連接到VibratorService,與底層的系統(tǒng)服務(wù)進(jìn)行通信了:

IVibratorService.Stub.asInterface(ServiceManager.getService("vibrator"));
  • 1

mService相當(dāng)于IVibratorService在應(yīng)用層的一個(gè)代理,所有的實(shí)現(xiàn)還是在SystemServerVibratorService里。
看代碼時(shí)可以發(fā)現(xiàn)registerService是在static代碼塊里靜態(tài)調(diào)用的,所以getSystemServcr獲得的各個(gè)Manager也都是單例的。

System Service實(shí)現(xiàn)流程

從上面的分析,我們可以總結(jié)出Vibrator服務(wù)的整個(gè)實(shí)現(xiàn)流程:

  1. 定義一個(gè)抽象類Vibrator,定義了應(yīng)用中可以訪問的一些抽象方法
    frameworks/base/core/java/android/os/Vibrator.java
  2. 定義具體的類SystemVibrator繼承Vibrator,實(shí)現(xiàn)抽象方法
    frameworks/base/core/java/android/os/SystemVibrator.java
  3. 定義一個(gè)AIDL接口文件IVibratorService,定義系統(tǒng)服務(wù)接口
    frameworks/base/core/java/android/os/IVibratorService.aidl
  4. 定義服務(wù)VibratorService,實(shí)現(xiàn)IVibratorService定義的接口
    frameworks/base/services/java/com/android/server/VibratorService.java

    public class VibratorService extends IVibratorService.Stub
    • 1
  5. VibratorServicey添加到系統(tǒng)服務(wù)
    frameworks/base/services/java/com/android/server/SystemServer.java

    VibratorService vibrator = null;
    ...
    //實(shí)例化VibratorService并添加到ServiceManager
    Slog.i(TAG, "Vibrator Service");
    vibrator = new VibratorService(context);
    ServiceManager.addService("vibrator", vibrator);
    ...
    //通知服務(wù)系統(tǒng)啟動(dòng)完成
    try {
        vibrator.systemReady();
    } catch (Throwable e) {
        reportWtf("making Vibrator Service ready", e);
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  6. SystemVibrator中通過IVibratorService的代理連接到VibratorService,這樣SystemVibrator的接口實(shí)現(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) {
            }
            ...
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  7. Context里定義一個(gè)代表Vibrator服務(wù)的字符串
    frameworks/base/core/java/android/content/Context.java

    public static final String VIBRATOR_SERVICE = "vibrator";
    • 1
  8. 在ContextImpl里添加SystemVibrator的實(shí)例化過程
    frameworks/base/core/java/android/app/ContextImpl.java

    registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
    public Object createService(ContextImpl ctx) {
        return new SystemVibrator(ctx);
    }});  
    • 1
    • 2
    • 3
    • 4
  9. 在應(yīng)用中使用Vibrator的接口

    Vibrator mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
    mVibrator.vibrate(500);
    • 1
    • 2
  10. 為保證編譯正常,還需要將AIDL文件添加到編譯配置里
    frameworks/base/Android.mk

    LOCAL_SRC_FILES += ...
    core/java/android/os/IVibratorService.aidl \
    • 1
    • 2
    • 3

System Service 新加接口

如果我們需要實(shí)現(xiàn)一個(gè)新的系統(tǒng)服務(wù),就可以按照上面的步驟在系統(tǒng)中擴(kuò)展出一個(gè)新的服務(wù),并給應(yīng)用層提供出使用接口。如果想在Vibrator里添加一個(gè)新的接口,需要下面3步:

  1. IVibratorService添加接口;
  2. VibratorService添加接口的實(shí)現(xiàn);
  3. VibratorSystemVibrator里擴(kuò)展新的接口;

這樣應(yīng)用中就可以使用Vibrator的新接口了。

應(yīng)用層與 System Service 通信

上面的實(shí)現(xiàn)我們看到的只是從應(yīng)用層通過服務(wù)代理,調(diào)用系統(tǒng)服務(wù)的接口,如果我們想反過來,將系統(tǒng)服務(wù)的狀態(tài)通知給應(yīng)用層,該怎么做呢?

  • 方法一:使用Broadcast

我們知道使用Broadcast廣播可以實(shí)現(xiàn)跨進(jìn)程的消息傳遞,一些系統(tǒng)服務(wù)也使用了這種方法。如電池管理服務(wù)BatteryManagerService,收到底層上報(bào)的電池狀態(tài)變化信息時(shí),就將當(dāng)前的電池狀態(tài)封裝在一個(gè)Intent里,actionandroid.intent.action.BATTERY_CHANGED。應(yīng)用只要注冊(cè)一個(gè)對(duì)應(yīng)的BroadcastReceiver就可以收到BatterManagerService發(fā)送的電池狀態(tài)信息。

  • 方法二:使用AIDL
    從上面我們可以知道,通過AIDL定義一套接口,由系統(tǒng)服務(wù)端實(shí)現(xiàn)這些接口,應(yīng)用端使用一個(gè)相應(yīng)的代理就可以訪問系統(tǒng)服務(wù)的接口,那反過來讓應(yīng)用端實(shí)現(xiàn)AIDL接口,系統(tǒng)服務(wù)端使用代理調(diào)用應(yīng)用端的接口可不可以呢?答案是YES。那么接下來的問題是怎么讓系統(tǒng)服務(wù)得到這個(gè)代理。我們?cè)賮砜匆粋€(gè)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)聽到位置信息
    }
    ...
};

//注冊(cè)監(jiān)聽器
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 
        0, 0, locationListener);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

從上面的代碼可以看到,我們創(chuàng)建了一個(gè)位置監(jiān)聽器LocationListener,并將這個(gè)監(jiān)聽器在LocationManager里進(jìn)行了注冊(cè)。當(dāng)系統(tǒng)定位到系統(tǒng)的位置后,就會(huì)回調(diào)監(jiān)聽器的onLocationChanged(),將位置信息通知給監(jiān)聽器。LocationListener就是一個(gè)系統(tǒng)服務(wù)調(diào)用應(yīng)用層接口的例子,我們就研究一下LocationListener的實(shí)現(xiàn)方式。
我們先從LocationManager怎么注冊(cè)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);
   }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

可以看到LocationListener被重新封裝成了一個(gè)ListenerTransport,然后傳遞給了ILocationManager ,從前面的分析可以猜測(cè)到這個(gè)ILocationManager應(yīng)該就是LocationManagerService的一個(gè)代理。那么ListenerTransport又是什么呢?搜索LocationManager.java可以找到:

private class ListenerTransport extends ILocationListener.Stub {
    ...
    @Override
    public void onLocationChanged(Location location) {
        ...
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

原來是ILocationListener.Stub的一個(gè)繼承實(shí)現(xiàn),那么ILocationListener應(yīng)該就是一個(gè)AIDL接口定義:
frameworks/base/location/java/android/location/ILocationListener.aidl

oneway interface ILocationListener
{
    void onLocationChanged(in Location location);
    ...
}
  • 1
  • 2
  • 3
  • 4
  • 5

而在LocationManagerService里只要調(diào)用ILocationListener的方法就可以將消息傳遞給應(yīng)用層的監(jiān)聽:

mListener.onLocationChanged(new Location(location));
  • 1

實(shí)現(xiàn) System Service 的注意事項(xiàng)

  1. 注意防止阻塞
    應(yīng)用層訪問系統(tǒng)服務(wù)提供的接口時(shí)會(huì)有兩種情況:

    • 一種是應(yīng)用調(diào)用端需要等待服務(wù)實(shí)現(xiàn)端處理完成,返回處理結(jié)果,這樣如果服務(wù)端發(fā)生阻塞,那么應(yīng)用端也會(huì)發(fā)生阻塞,因此在實(shí)現(xiàn)服務(wù)端的實(shí)現(xiàn)時(shí)要注意不要發(fā)生阻塞。
    • 另一種是調(diào)用端不需要等待服務(wù)端返回結(jié)果,調(diào)用完成后直接返回void,這樣服務(wù)端發(fā)生阻塞不會(huì)影響到應(yīng)用端,這樣的單向的接口在AIDL里定義時(shí)需要添加oneway關(guān)鍵字,如:
    oneway void statusBarVisibilityChanged(int visibility);
    • 1

    對(duì)于需要在服務(wù)端調(diào)用,在應(yīng)用端實(shí)現(xiàn)的接口,考慮到系統(tǒng)的穩(wěn)定性以及安全性,一般都會(huì)設(shè)計(jì)成上面的第二種,即AIDL里所有的接口都是單向的,如上面的ILocationListener

    oneway interface ILocationListener
    • 1
  2. 注意多線程訪問
    每個(gè)系統(tǒng)服務(wù)在系統(tǒng)進(jìn)程中只有一個(gè)實(shí)例,而且應(yīng)用中系統(tǒng)服務(wù)的代理也是單例的,而且應(yīng)用端的訪問,在系統(tǒng)進(jìn)程都是使用獨(dú)立的線程進(jìn)行響應(yīng),所以訪問同一個(gè)系統(tǒng)服務(wù)的接口時(shí)必然會(huì)出現(xiàn)多個(gè)線程或者多個(gè)進(jìn)程同時(shí)訪問的情況。為保證系統(tǒng)服務(wù)的線程安全,需要對(duì)系統(tǒng)服務(wù)的進(jìn)程進(jìn)行多線程訪問的保護(hù),目前主要有兩種實(shí)現(xiàn)線程安全的方法:

    • 一種是通過同步鎖機(jī)制,鎖住一個(gè)對(duì)象實(shí)例(一般是這個(gè)服務(wù)對(duì)象本身),這樣這個(gè)服務(wù)同一時(shí)間只能響應(yīng)一個(gè)訪問請(qǐng)求,如LocationManagerService里:
    public boolean callStatusChangedLocked(...) {
        ...
        synchronized (this) {
        ...
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 另一種方法就是使用Handler機(jī)制,這種服務(wù)一般會(huì)創(chuàng)建一個(gè)單獨(dú)的線程,當(dāng)有應(yīng)用端訪問請(qǐng)求到來時(shí)會(huì)向服務(wù)線程的Handler里發(fā)送一個(gè)Message,利用單線程順序執(zhí)行的特性,保證所有的訪問都按順序進(jìn)行處理,但這種方法只適合單向的訪問,不適合需要返回的雙向訪問。

ServiceManager原理

從上面流程的分析我們可以看到,所有的系統(tǒng)服務(wù)最終都是由ServiceManager來管理的,那么ServiceManager是怎么管理這些系統(tǒng)服務(wù)的呢?還是先看上面的VibratorService的實(shí)現(xiàn):

VibratorService通過addService()將自己注冊(cè)到ServiceManager里,SystemVibrator通過getService()獲得一個(gè)服務(wù)代理,并與服務(wù)進(jìn)行通信交互,那么ServiceManager又是什么?它是怎么管理服務(wù)的注冊(cè)與代理的呢?我們先從addService()getService()開始,分析一下ServiceManager:
frameworks/base/core/java/android/os/ServiceManager.java

public final class ServiceManager {
    public static void addService(String name, IBinder service) {
        ...
        getIServiceManager().addService(name, service, false);
    }

    public static IBinder getService(String name) {
        ...
        return getIServiceManager().getService(name);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

這里是創(chuàng)建了一個(gè)IServiceManager類型的單實(shí)例,具體的實(shí)例又是通過ServiceManagerNative創(chuàng)建的:

ServiceManagerNative.asInterface(BinderInternal.getContextObject());
  • 1

先來看BinderInternal.getContextObject()
frameworks/base/core/java/com/android/internal/os/BinderInternal.java

public static final native IBinder getContextObject();
  • 1

getContextObject()是在native層實(shí)現(xiàn)的
frameworks/base/core/jni/android_util_Binder.cpp

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, 
        jobject clazz)
{
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    return javaObjectForIBinder(env, b);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

后面的實(shí)現(xiàn)過程邏輯比較復(fù)雜,這里就不詳細(xì)分析了,只是說明一下大致流程,感興趣的可以自己詳細(xì)研究一下binder的實(shí)現(xiàn)機(jī)制。
ProcessState從名字可以看出這應(yīng)該是一個(gè)保存進(jìn)程狀態(tài)的類,最好應(yīng)該用單實(shí)例的對(duì)象保存,所以ProcessState::self()得到的也就是ProcessState的一個(gè)單實(shí)例對(duì)象,它的getContextObject()會(huì)繼續(xù)調(diào)用getStrongProxyForHandle(int32_t handle)返回一個(gè)IBinder
frameworks/native/libs/binder/ProcessState.cpp

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
{
    return getStrongProxyForHandle(0);
}
  • 1
  • 2
  • 3
  • 4

getStrongProxyForHandle()中會(huì)根據(jù)傳入的參數(shù)handle創(chuàng)建一個(gè)BpBinder,這個(gè)BpBinder會(huì)保存在一個(gè)數(shù)組mHandleToObject中,下次再用同樣的handle請(qǐng)求時(shí)不會(huì)再重新創(chuàng)建。由于我們傳入的handle=0,這里創(chuàng)建的BpBinder也就相當(dāng)于第0號(hào)BpBinder。
之后的javaObjectForIBinder()會(huì)將C++的BpBinder對(duì)象封裝成Java的BinderProxy對(duì)象并返回。所以BinderInternal.getContextObject()得到的是一個(gè)BinderProxy對(duì)象,并關(guān)聯(lián)了native層的第0號(hào)BpBinder

ServiceManagerNative.asInterface(BinderInternal.getContextObject());
  • 1

相當(dāng)于

ServiceManagerNative.asInterface(new BinderProxy());
  • 1

ServiceManagerNative.asInterface()又做了些什么呢?
frameworks/base/core/java/android/os/ServiceManagerNative.java

static public IServiceManager asInterface(IBinder obj)
{
    ...    
    return new ServiceManagerProxy(obj);
}
  • 1
  • 2
  • 3
  • 4
  • 5

這里會(huì)將BinderProxy再封裝成一個(gè)ServiceManagerProxy(),所以getIServiceManager()得到的其實(shí)是一個(gè)ServiceManagerProxy,但是底層指向的是一個(gè)BpBinder(0)。
ServiceManagerProxy、BinderProxy以及BpBinder都是代理模式中的proxy端,真正的實(shí)現(xiàn)應(yīng)該在對(duì)應(yīng)的native端。我們接著看。
addService()getService()在代理端的實(shí)現(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();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

從上面兩個(gè)方法的實(shí)現(xiàn)可以看到,首先是創(chuàng)建了兩個(gè)可序列化的Parcel datareply,傳入的參數(shù)被放到了data里,datareply又一起傳給了mRemote.transact(),之后又從reply里讀取結(jié)果。addService()的實(shí)現(xiàn)里還通過data.writeStrongBinder(service)寫入了一個(gè)IBinder的實(shí)例。同時(shí)注意到getService()addService()里面調(diào)用mRemote.transact()傳遞的第一個(gè)參數(shù)分別為GET_SERVICE_TRANSACTIONADD_SERVICE_TRANSACTION ,我們可以在IServiceManager里看到這是兩個(gè)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;
  • 1
  • 2
  • 3

mRemote就是BinderProxy,真正的實(shí)現(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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

IPCThreadState里的transact會(huì)將proxy端的請(qǐng)求通過binder機(jī)制寫入到一塊共享內(nèi)存里,然后會(huì)有一個(gè)native端從共享內(nèi)存里讀出請(qǐng)求,并執(zhí)行相應(yīng)的操作。那么這個(gè)native端在哪里呢?是不是ServiceManagerNative呢?但是ServiceManagerNative只是一個(gè)抽象類,我們并沒有找到繼承自它的子類。實(shí)際上ServiceManagerNative只是架構(gòu)方面的一個(gè)抽象定義,并沒有真正的一個(gè)實(shí)現(xiàn),真正實(shí)現(xiàn)ServiceManager 的native端功能的是在native層的service_manager.c中。
servicemanager是底層的一個(gè)獨(dú)立進(jìn)程,主要的實(shí)現(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,
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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;
        ...
    }
}
  • 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

service_manager.csvcmgr_handler函數(shù)就是監(jiān)聽代理端請(qǐng)求命令的txn->code就是mRemote.transact()里傳過來的第一個(gè)參數(shù)。SVC_MGR_GET_SERVICESVC_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)獲得了一個(gè)handle,這個(gè)handle就是我們之前通過writeStrongBinder寫入的IBinder
  • 最后通過do_add_service()添加注冊(cè)service

do_add_service()的實(shí)現(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;
}
  • 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
  • 首先聲明了一個(gè)struct svcinfo *si
  • 通過find_svc(s, len)查找一下同樣名稱的service之前是不是注冊(cè)過,防止重復(fù)注冊(cè)。find_svc()的實(shí)現(xiàn)里可以看到是通過遍歷一個(gè)svclist鏈表來查重的,svclist鏈表就是用來保存所有注冊(cè)過的service的
  • 如果確認(rèn)沒有重復(fù)注冊(cè)service,就重新構(gòu)造一個(gè)svcinfo添加到svclist鏈表的頭部。

我們?cè)倏?code>SVC_MGR_GET_SERVICE的響應(yīng),主要是通過do_find_service()查找到對(duì)應(yīng)的service,并通過bio_put_ref(reply, handle)將查找到的handle返回。do_find_service()的實(shí)現(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
  • 2
  • 3
  • 4
  • 5
  • 6

通過上面的流程梳理我們最終了解到:

  • 每個(gè)System Service通過調(diào)用ServiceManager.addService()將自己的名字以及IBinder引用保存到servicemanager進(jìn)程的一個(gè)鏈表里
  • 每個(gè)使用該System Service的進(jìn)程通過調(diào)用ServiceManager.getService()從servicemanager進(jìn)程獲得該System Service對(duì)應(yīng)的IBinder,就可以與該System Service進(jìn)行通信了。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多