AndroidはContext-ServiceにおけるContextの作成過程を深く理解している
4241 ワード
このシリーズは4つの文章に分けてContextを詳しく紹介して、これは第3編です Android Context–ApplicationにおけるContextの作成プロセス を深く理解 Android Context–ActivityにおけるContextの作成プロセス を深く理解 Android Context–ServiceにおけるContextの作成プロセス を深く理解 Android Context–Context使用の誤り を深く理解本明細書はサービスのContext作成プロセスを分析するため、 注記 注記 注記 注記 注釈 注釈 注釈 に入ります.は、最終的には、サービスタイプのContextImplをContextWrapperの これでサービスに関するContextの分析は終わります.
ActivityThread.handleCreateService
から直接分析を開始します.これまでの論理がよく分からない場合は、サービスを参照してプロセスソース分析を開始できます.@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
で、サービスのContextImplオブジェクトを作成します.3
でsetOuterContext
は、サービスオブジェクトをContextImplのmOuterContext
に割り当て、ContextImplがサービスのメソッドおよび変数にアクセスできるようにします.4
でApplicationを作成し、前述のAndroidでContextを深く理解しています.5
でservice.attach
が呼び出され、作成されたcontextがサービスに渡される.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;
}
}
mBase
変数に割り当てます.これにより、ContextWrapperを呼び出す方法は、実際にはmBase
という本当のContextImplを呼び出す方法です.