本系列分四篇文章詳細介紹Context, 這是第三篇
-
因爲本文是分析Service的Context創建流程,我們直接從
ActivityThread.handleCreateService
開始分析,如果不太明白這之前的邏輯的話,可以參考Service啓動流程源碼分析。@UnsupportedAppUsage private void handleCreateService(CreateServiceData data) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); Service service = null; try { //-----1----- java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = packageInfo.getAppFactory() .instantiateService(cl, data.info.name, data.intent); } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to instantiate service " + data.info.name + ": " + e.toString(), e); } } try { if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); //-----2----- ContextImpl context = ContextImpl.createAppContext(this, packageInfo); //-----3----- context.setOuterContext(service); //-----4----- Application app = packageInfo.makeApplication(false, mInstrumentation); //-----5----- service.attach(context, this, data.info.name, data.token, app, ActivityManager.getService()); //-----6----- service.onCreate(); mServices.put(data.token, service); try { ActivityManager.getService().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to create service " + data.info.name + ": " + e.toString(), e); } } }
-
註釋
1
處創建一個service
對象。 -
註釋
2
處創建一個Service的ContextImpl對象。 -
註釋
3
處setOuterContext
將service對象賦值給ContextImpl中的mOuterContext
, 這樣ContextImpl就可以訪問service中的方法和變量了。 -
註釋
4
處創建一個Application,在前面Android深入理解Context講過。 -
註釋
5
處調用service.attach
,將創建的context傳遞進service中。 -
註釋
6
處調用service.onCreate()
。 -
我們主要看下注釋
4
的代碼部分,進入service.attach
:public abstract class Service extends ContextWrapper { @UnsupportedAppUsage public final void attach( Context context, ActivityThread thread, String className, IBinder token, Application application, Object activityManager) { attachBaseContext(context); mThread = thread; // NOTE: unused - remove? mClassName = className; mToken = token; mApplication = application; mActivityManager = (IActivityManager)activityManager; mStartCompatibility = getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.ECLAIR; } } public class ContextWrapper extends Context { protected void attachBaseContext(Context base) { if (mBase != null) { throw new IllegalStateException("Base context already set"); } mBase = base; } }
-
最終還是將Service類型的ContextImpl賦值給了ContextWrapper中的
mBase
變量,這樣我們調用ContextWrapper中的方法實際就是調用mBase
這個真正的ContextImpl中的方法。 -
至此我們關於Service的Context的分析就結束了。