亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

android servicemanager與binder源碼分析二 ------ servicem

Anleb / 824人閱讀

摘要:也同時(shí)可以看到責(zé)任鏈的應(yīng)用,一個(gè)請(qǐng)求從上到下會(huì)經(jīng)過很多層,每層都只處理和自己相關(guān)的部分,如果沒有則交由下層繼續(xù)傳遞,如果有直接返回。因此雖然看著費(fèi)勁點(diǎn),但是在此還是要對(duì)搞操作系統(tǒng)的以及研究操作系統(tǒng)的人們給予敬意。

承接上篇,serviceManager是怎么被調(diào)用的呢?如何為app提供服務(wù)支持?怎么銜接的?。這次我打算從最上層開始逐步把脈絡(luò)屢清楚。
首先,我們?cè)趯慳pp的時(shí)候需要使用AudioManager這類東西的時(shí)候,都要調(diào)用context.getSystemService(Context.AUDIO_SERVICE);獲取服務(wù)。逐層看下代碼:

a.activity的getSystemService:

@Override
    public Object getSystemService(String name) {
        if (getBaseContext() == null) {
            throw new IllegalStateException(
                    "System services not available to Activities before onCreate()");
        }

        if (WINDOW_SERVICE.equals(name)) {
            return mWindowManager;
        } else if (SEARCH_SERVICE.equals(name)) {
            ensureSearchManager();
            return mSearchManager;
        }
        return super.getSystemService(name);
    }

如果是WINDOW_SERVICE或者SEARCH_SERVICE,直接在activity這里就做了處理返回了,否則調(diào)用super的同名方法。
b.ContextThemeWrapper的getSystemService:

@Override public Object getSystemService(String name) {
        if (LAYOUT_INFLATER_SERVICE.equals(name)) {
            if (mInflater == null) {
                mInflater = LayoutInflater.from(mBase).cloneInContext(this);
            }
            return mInflater;
        }
        return mBase.getSystemService(name);
    }

如果是LAYOUT_INFLATER_SERVICE,在這里直接返回,否則調(diào)用mBase的同名方法。
mBase是Context類型,那么其實(shí)就是ContextImpl??聪拢?/p>

1363    @Override
1364    public Object getSystemService(String name) {
1365        return SystemServiceRegistry.getSystemService(this, name);
1366    }

SystemServiceRegistry.java:

716    /**
717     * Gets a system service from a given context.
718     */
719    public static Object getSystemService(ContextImpl ctx, String name) {
720        ServiceFetcher fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
721        return fetcher != null ? fetcher.getService(ctx) : null;
722    }
133    private static final HashMap> SYSTEM_SERVICE_FETCHERS =
134            new HashMap>();

這么逐層看來,你請(qǐng)求的內(nèi)容在每層都分別回應(yīng)自己所關(guān)心的,如果不關(guān)心,交給父類處理,最后會(huì)走到SystemServiceRegistry類中,看定義就明白,使用一個(gè)hashmap來存儲(chǔ)名字和ServiceFetcher的對(duì)應(yīng)關(guān)系。那么看到這里大體應(yīng)該有個(gè)了解了,SystemServiceRegistry來維護(hù)注冊(cè)進(jìn)去的所有服務(wù),當(dāng)然是其他層級(jí)上不關(guān)心的。
也同時(shí)可以看到責(zé)任鏈的應(yīng)用,一個(gè)請(qǐng)求從上到下會(huì)經(jīng)過很多層,每層都只處理和自己相關(guān)的部分,如果沒有則交由下層繼續(xù)傳遞,如果有直接返回。這種模式的使用其實(shí)已經(jīng)在很多年前就非常廣泛了,比如tcp/ip的封包和解包過程,比如windows下的層級(jí)調(diào)用,再比如android的ui event相應(yīng)等都采用了類似的思想。不要較真兒說這里是繼承那邊是調(diào)用鏈?zhǔn)裁吹?,我覺得還是看整體思想為好,不需要拘泥于具體什么什么模式,什么什么規(guī)則。
再繼續(xù)看SystemServiceRegistry這個(gè)類,靜態(tài)類一個(gè),連構(gòu)造都隱藏了,但不是單例,直接在static中進(jìn)行了很多服務(wù)的注冊(cè):

140    static {
141        registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
142                new CachedServiceFetcher() {
143            @Override
144            public AccessibilityManager createService(ContextImpl ctx) {
145                return AccessibilityManager.getInstance(ctx);
146            }});
147
148        registerService(Context.CAPTIONING_SERVICE, CaptioningManager.class,
149                new CachedServiceFetcher() {
150            @Override
151            public CaptioningManager createService(ContextImpl ctx) {
152                return new CaptioningManager(ctx);
153            }});
154        ......
707    }

這里使用了靜態(tài)代碼塊static,在類被加載的時(shí)候必然會(huì)走這里。
往下看registerService:

732     * Statically registers a system service with the context.
733     * This method must be called during static initialization only.
734     */
735    private static  void registerService(String serviceName, Class serviceClass,
736            ServiceFetcher serviceFetcher) {
737        SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
738        SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
739    }

只是向兩個(gè)hashmap中填充了名字和class而已。在這里已經(jīng)實(shí)例化了。
簡(jiǎn)單看下ServiceFetcher:

741    /**
742     * Base interface for classes that fetch services.
743     * These objects must only be created during static initialization.
744     */
745    static abstract interface ServiceFetcher {
746        T getService(ContextImpl ctx);
747    }

只是個(gè)包裝interface,根據(jù)類型不同提供了3種子類供各個(gè)服務(wù)使用:

749    /**
750     * Override this class when the system service constructor needs a
751     * ContextImpl and should be cached and retained by that context.
752     */
753    static abstract class CachedServiceFetcher implements ServiceFetcher {
754        private final int mCacheIndex;
755
756        public CachedServiceFetcher() {
757            mCacheIndex = sServiceCacheSize++;
758        }
759
760        @Override
761        @SuppressWarnings("unchecked")
762        public final T getService(ContextImpl ctx) {
763            final Object[] cache = ctx.mServiceCache;
764            synchronized (cache) {
765                // Fetch or create the service.
766                Object service = cache[mCacheIndex];
767                if (service == null) {
768                    service = createService(ctx);
769                    cache[mCacheIndex] = service;
770                }
771                return (T)service;
772            }
773        }
774
775        public abstract T createService(ContextImpl ctx);
776    }
777
778    /**
779     * Override this class when the system service does not need a ContextImpl
780     * and should be cached and retained process-wide.
781     */
782    static abstract class StaticServiceFetcher implements ServiceFetcher {
783        private T mCachedInstance;
784
785        @Override
786        public final T getService(ContextImpl unused) {
787            synchronized (StaticServiceFetcher.this) {
788                if (mCachedInstance == null) {
789                    mCachedInstance = createService();
790                }
791                return mCachedInstance;
792            }
793        }
794
795        public abstract T createService();
796    }
797
798    /**
799     * Like StaticServiceFetcher, creates only one instance of the service per process, but when
800     * creating the service for the first time, passes it the outer context of the creating
801     * component.
802     *
803     * TODO: Is this safe in the case where multiple applications share the same process?
804     * TODO: Delete this once its only user (ConnectivityManager) is known to work well in the
805     * case where multiple application components each have their own ConnectivityManager object.
806     */
807    static abstract class StaticOuterContextServiceFetcher implements ServiceFetcher {
808        private T mCachedInstance;
809
810        @Override
811        public final T getService(ContextImpl ctx) {
812            synchronized (StaticOuterContextServiceFetcher.this) {
813                if (mCachedInstance == null) {
814                    mCachedInstance = createService(ctx.getOuterContext());
815                }
816                return mCachedInstance;
817            }
818        }
819
820        public abstract T createService(Context applicationContext);
821    }
822
823}

暫時(shí)不深究到底這3種是什么用途,不過都可看到getService內(nèi)部會(huì)走到createService(ctx);中,而這個(gè)抽象方法是必須被實(shí)現(xiàn)的。然后在static代碼塊中注冊(cè)服務(wù)的時(shí)候都要有選擇的去根據(jù)這3種類型實(shí)現(xiàn)ServiceFetcher,實(shí)現(xiàn)createService。那么無論這個(gè)服務(wù)是單例非單例,或者在創(chuàng)建的時(shí)候需要做什么事情,都可以在這個(gè)createService中來進(jìn)行。那么這3類里面又使用了惰性加載,如果緩存有或者單例有就不用走createService,沒有的時(shí)候就走。
回過頭來看,getService最終返回的是一個(gè)注冊(cè)過的服務(wù)的實(shí)例化對(duì)象。
說了這么半天,跟servicemanager有什么關(guān)系?其實(shí)在于getService的實(shí)現(xiàn)上。以AudioManager為例 /frameworks/base/media/java/android/media/AudioManager.java:

655    private static IAudioService getService()
656    {
657        if (sService != null) {
658            return sService;
659        }
660        IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
661        sService = IAudioService.Stub.asInterface(b);
662        return sService;
663    }

看到了吧,這里已經(jīng)開始對(duì)ServiceManager的使用了,并且是通過binder來得到的。那么結(jié)合之前的分析,ServiceManager是在一個(gè)獨(dú)立的進(jìn)程中的,那么其他進(jìn)程要是想通過它拿到Service等操作,就需要借助Binder這個(gè)跨進(jìn)程的通訊方式。再往下看:
/frameworks/base/core/java/android/os/ServiceManager.java:

43    /**
44     * Returns a reference to a service with the given name.
45     *
46     * @param name the name of the service to get
47     * @return a reference to the service, or null if the service doesn"t exist
48     */
49    public static IBinder getService(String name) {
50        try {
51            IBinder service = sCache.get(name);
52            if (service != null) {
53                return service;
54            } else {
55                return getIServiceManager().getService(name);
56            }
57        } catch (RemoteException e) {
58            Log.e(TAG, "error in getService", e);
59        }
60        return null;
61    }

簡(jiǎn)單說:先從緩存中拿,如果沒有通過getIServiceManager()去拿,看getIServiceManager:

33    private static IServiceManager getIServiceManager() {
34        if (sServiceManager != null) {
35            return sServiceManager;
36        }
37
38        // Find the service manager
39        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
40        return sServiceManager;
41    }

單例,然后調(diào)用到ServiceManagerNative.asInterface,繼續(xù)看:
/frameworks/base/core/java/android/os/ServiceManagerNative.java:

33    static public IServiceManager asInterface(IBinder obj)
34    {
35        if (obj == null) {
36            return null;
37        }
38        IServiceManager in =
39            (IServiceManager)obj.queryLocalInterface(descriptor);
40        if (in != null) {
41            return in;
42        }
43
44        return new ServiceManagerProxy(obj);
45    }

通過IBinder對(duì)象去查詢本地接口,如果沒查到需要幫助,就建立一個(gè)ServiceManagerProxy。這個(gè)代理對(duì)象是這樣的:

109class ServiceManagerProxy implements IServiceManager {
110    public ServiceManagerProxy(IBinder remote) {
111        mRemote = remote;
112    }
113
114    public IBinder asBinder() {
115        return mRemote;
116    }
117
118    public IBinder getService(String name) throws RemoteException {
119        Parcel data = Parcel.obtain();
120        Parcel reply = Parcel.obtain();
121        data.writeInterfaceToken(IServiceManager.descriptor);
122        data.writeString(name);
123        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
124        IBinder binder = reply.readStrongBinder();
125        reply.recycle();
126        data.recycle();
127        return binder;
128    }
129
130    public IBinder checkService(String name) throws RemoteException {
131        Parcel data = Parcel.obtain();
132        Parcel reply = Parcel.obtain();
133        data.writeInterfaceToken(IServiceManager.descriptor);
134        data.writeString(name);
135        mRemote.transact(CHECK_SERVICE_TRANSACTION, data, reply, 0);
136        IBinder binder = reply.readStrongBinder();
137        reply.recycle();
138        data.recycle();
139        return binder;
140    }
141
142    public void addService(String name, IBinder service, boolean allowIsolated)
143            throws RemoteException {
144        Parcel data = Parcel.obtain();
145        Parcel reply = Parcel.obtain();
146        data.writeInterfaceToken(IServiceManager.descriptor);
147        data.writeString(name);
148        data.writeStrongBinder(service);
149        data.writeInt(allowIsolated ? 1 : 0);
150        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
151        reply.recycle();
152        data.recycle();
153    }
154
155    public String[] listServices() throws RemoteException {
156        ArrayList services = new ArrayList();
157        int n = 0;
158        while (true) {
159            Parcel data = Parcel.obtain();
160            Parcel reply = Parcel.obtain();
161            data.writeInterfaceToken(IServiceManager.descriptor);
162            data.writeInt(n);
163            n++;
164            try {
165                boolean res = mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
166                if (!res) {
167                    break;
168                }
169            } catch (RuntimeException e) {
170                // The result code that is returned by the C++ code can
171                // cause the call to throw an exception back instead of
172                // returning a nice result...  so eat it here and go on.
173                break;
174            }
175            services.add(reply.readString());
176            reply.recycle();
177            data.recycle();
178        }
179        String[] array = new String[services.size()];
180        services.toArray(array);
181        return array;
182    }
183
184    public void setPermissionController(IPermissionController controller)
185            throws RemoteException {
186        Parcel data = Parcel.obtain();
187        Parcel reply = Parcel.obtain();
188        data.writeInterfaceToken(IServiceManager.descriptor);
189        data.writeStrongBinder(controller.asBinder());
190        mRemote.transact(SET_PERMISSION_CONTROLLER_TRANSACTION, data, reply, 0);
191        reply.recycle();
192        data.recycle();
193    }
194
195    private IBinder mRemote;
196}

至此,已經(jīng)開始進(jìn)入binder的跨進(jìn)程部分,可以看到其中的getService函數(shù)是怎么運(yùn)作的:
1.建立2個(gè)Parcel數(shù)據(jù)data和reply,一個(gè)是入口數(shù)據(jù),一個(gè)是出口數(shù)據(jù);
2.data中寫入要獲取的service的name;
3.關(guān)鍵:走mRemote的transact函數(shù);
4.讀取出口數(shù)據(jù);
5.回收資源,返回讀取到的binder對(duì)象;

夠暈吧,這一通調(diào)用,但是這部分沒辦法,實(shí)在不好層級(jí)總結(jié),只能是一口氣跟著調(diào)用走下來,然后回過頭再看。上面那么多步驟的調(diào)用都是為了這最后一步做準(zhǔn)備,那么為什么要分為這么多層次呢?任何一個(gè)操作系統(tǒng)都是非常復(fù)雜的,每個(gè)地方都要考慮到很多的擴(kuò)展性及健壯性,隨時(shí)可以在某個(gè)版本或補(bǔ)丁上去除或擴(kuò)展出一些內(nèi)容來。也為了利于多人協(xié)作,那么分層的調(diào)用能夠保證在每一個(gè)層級(jí)上都有可擴(kuò)展的余地,再進(jìn)行修改的時(shí)候不至于要?jiǎng)雍芏啻a,動(dòng)的越少就越不容易出錯(cuò)。因此雖然看著費(fèi)勁點(diǎn),但是在此還是要對(duì)搞操作系統(tǒng)的以及研究操作系統(tǒng)的人們給予敬意。

最后總結(jié)一下,這篇主要說的是從應(yīng)用層開始與servicemanager銜接的過程,是怎么將servicemanager應(yīng)用起來的。寫這篇的原因也是發(fā)現(xiàn)網(wǎng)上這部分的銜接的資料較少,我覺得梳理一下還是有助于理解系統(tǒng)的機(jī)制的,難點(diǎn)并不多,只是幫助理解系統(tǒng)的機(jī)制,作為參考吧。順便再說下,如果你的興趣在于底層,那么不看此文也罷,不過我的建議是不僅要了解各個(gè)環(huán)節(jié)的運(yùn)作機(jī)制,還要在一個(gè)更高的角度去看待每個(gè)環(huán)節(jié)的銜接過程,否則可能你費(fèi)勁心血在底層做了各種優(yōu)化后發(fā)現(xiàn)效率還是上不來,那么往往問題出在銜接過程。當(dāng)然這么龐大復(fù)雜的系統(tǒng)不可能是一個(gè)人寫的,每個(gè)人的能力也各有差別,瓶頸總會(huì)有的,但是如果你站的夠高,那么架構(gòu)的角度去理解每個(gè)細(xì)節(jié)及銜接,就能夠找出問題所在。不是嗎?總之都是個(gè)人愚見而已,各位海涵。

下面該說binder的遠(yuǎn)程通訊機(jī)制內(nèi)部的內(nèi)容了,下一篇文我會(huì)繼續(xù)的。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/65001.html

相關(guān)文章

  • android servicemanagerbinder源碼分析(暫時(shí)作廢,后面會(huì)重新整理)

    摘要:抱歉,此文暫時(shí)作廢,不會(huì)使用的刪除功能。我會(huì)在后面重新整理后再繼續(xù)寫下去。是內(nèi)部的一個(gè)機(jī)制,通過設(shè)備驅(qū)動(dòng)的協(xié)助能夠起到進(jìn)程間通訊的的作用。這個(gè)應(yīng)該是個(gè)全局表,統(tǒng)計(jì)所有結(jié)構(gòu)。實(shí)際上是保存在打開的設(shè)備文件的結(jié)構(gòu)中。目前還未涉及到其他操作,只是。 抱歉,此文暫時(shí)作廢,不會(huì)使用segmentfault的刪除功能。我會(huì)在后面重新整理后再繼續(xù)寫下去。 繼續(xù)上篇的文,這篇打算進(jìn)入到android的內(nèi)...

    Ocean 評(píng)論0 收藏0
  • android servicemanagerbinder源碼分析一 ------ native層的

    摘要:以版本源碼為例。源碼位于下打開驅(qū)動(dòng)設(shè)備,將自己作為的管理者,進(jìn)入循環(huán),作為等待的請(qǐng)求位于首先,建立一個(gè)結(jié)構(gòu)體,然后剩下的就是給這個(gè)結(jié)構(gòu)體的成員賦值。同屬于這一層,因此我們看看具體內(nèi)容剛才從驅(qū)動(dòng)設(shè)備讀取的的前位取出來作為進(jìn)行判斷處理。 前一陣子在忙項(xiàng)目,沒什么更新,這次開始寫點(diǎn)android源碼內(nèi)部的東西分析下。以6.0.1_r10版本android源碼為例。servicemanager...

    馬忠志 評(píng)論0 收藏0
  • android servicemanagerbinder源碼分析三------如何進(jìn)入內(nèi)核通訊

    摘要:的構(gòu)造傳遞進(jìn)入的就是。如果狀態(tài)是,直接返回。到底是否正確呢看代碼先創(chuàng)建一個(gè)對(duì)象,這個(gè)對(duì)象是個(gè)存儲(chǔ)讀寫內(nèi)容的對(duì)象。然后終于進(jìn)入了內(nèi)核驅(qū)動(dòng)的部分。 承接上文,從getService開始,要開始走binder的通訊機(jī)制了。首先是上文的java層 /frameworks/base/core/java/android/os/ServiceManagerNative.java: 118 pu...

    lijy91 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<