Activity,ServiceとContext
8095 ワード
Activityの作成プロセス ActivityThread.java
に遡るperformLaunchActivity
メソッド:private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
//1. LoadedApk
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
.......
//2. ContextImpl appContext
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
//3. Activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
try {
//4. Application app
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
........
//appContext ContextImpl , activity
appContext.setOuterContext(activity);
//appContext window
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigpurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
......
activity.mCalled = false;
if (r.isPersistable()) {
//5. activity onCreate
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
........
return activity;
}
1.LoadedApk
オブジェクトを取得する.ContextImpl
オブジェクトappContext
を作成する.Activity
オブジェクトactivity
を作成する.Application
オブジェクトapp
を作成する.activity
を呼び出すonCreate
メソッド起動
サービス作成プロセス service
の作成とactivity
の作成は類似しています.ActivityThread.java
のhandleCreateService
メソッド:private void handleCreateService(CreateServiceData data) {
.....
//1. LoadedApk
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
//2. service
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) {
....
}
try {
.....
// 3. ContextImpl context
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
//4. Application app
Application app = packageInfo.makeApplication(false, mInstrumentation);
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//5. service onCreate
service.onCreate();
mServices.put(data.token, service);
.....
} catch (Exception e) {
......
}
}
1.LoadedApk
オブジェクトを取得する.service
オブジェクト3を作成する.ContextImpl
オブジェクトcontext 4を作成する.Application
オブジェクトapp 5を作成する.Service
を呼び出すonCreate
メソッドApplication
は最終的にInstrumentation.java
のnewApplication()
メソッドによって作成された. static public Application newApplication(Class> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
ここでは、ContextImpl
のsetOuterContext
に設定されているcontext
の違いを発見しました.
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
//1. LoadedApk
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
.......
//2. ContextImpl appContext
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
//3. Activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
try {
//4. Application app
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
........
//appContext ContextImpl , activity
appContext.setOuterContext(activity);
//appContext window
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigpurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
......
activity.mCalled = false;
if (r.isPersistable()) {
//5. activity onCreate
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
........
return activity;
}
service
の作成とactivity
の作成は類似しています.ActivityThread.java
のhandleCreateService
メソッド:private void handleCreateService(CreateServiceData data) {
.....
//1. LoadedApk
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
//2. service
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) {
....
}
try {
.....
// 3. ContextImpl context
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
//4. Application app
Application app = packageInfo.makeApplication(false, mInstrumentation);
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//5. service onCreate
service.onCreate();
mServices.put(data.token, service);
.....
} catch (Exception e) {
......
}
}
1.
LoadedApk
オブジェクトを取得する.service
オブジェクト3を作成する.ContextImpl
オブジェクトcontext 4を作成する.Application
オブジェクトapp 5を作成する.Service
を呼び出すonCreate
メソッドApplication
は最終的にInstrumentation.java
のnewApplication()
メソッドによって作成された. static public Application newApplication(Class> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
ここでは、
ContextImpl
のsetOuterContext
に設定されているcontext
の違いを発見しました.performLaunchActivity
------ activity
//appContext ContextImpl
appContext.setOuterContext(activity);
makeApplication
----- application
Application app = null;
.....
appContext.setOuterContext(app);
handleCreateService
---- service
context.setOuterContext(service);
Activity contextの作成 ContextImpl appContext = createBaseContextForActivity(r);
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
....
// appContext,
ContextImpl appContext = ContextImpl.createActivityContext(
this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
....
return appContext;
}
static ContextImpl createActivityContext(ActivityThread mainThread,
LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId,
Configuration overrideConfiguration) {
.....
// ContextImpl
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName,
activityToken, null, 0, classLoader);
// Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY.
displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY;
final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
? packageInfo.getCompatibilityInfo()
: CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
final ResourcesManager resourcesManager = ResourcesManager.getInstance();
// Create the base resources for which all configuration contexts for this Activity
// will be rebased upon.
// resources
context.setResources(resourcesManager.createBaseActivityResources(activityToken,
packageInfo.getResDir(),
splitDirs,
packageInfo.getOverlayDirs(),
packageInfo.getApplicationInfo().sharedLibraryFiles,
displayId,
overrideConfiguration,
compatInfo,
classLoader));
context.mDisplay = resourcesManager.getAdjustedDisplay(displayId,
context.getResources());
return context;
}
Service context作成 ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
createAppContext
メソッド:static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
null);
context.setResources(packageInfo.getResources());
return context;
}
以上、このActivity
とService
とContext
とのつながりを調べてみました.
ContextImpl appContext = createBaseContextForActivity(r);
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
....
// appContext,
ContextImpl appContext = ContextImpl.createActivityContext(
this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
....
return appContext;
}
static ContextImpl createActivityContext(ActivityThread mainThread,
LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId,
Configuration overrideConfiguration) {
.....
// ContextImpl
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName,
activityToken, null, 0, classLoader);
// Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY.
displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY;
final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
? packageInfo.getCompatibilityInfo()
: CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
final ResourcesManager resourcesManager = ResourcesManager.getInstance();
// Create the base resources for which all configuration contexts for this Activity
// will be rebased upon.
// resources
context.setResources(resourcesManager.createBaseActivityResources(activityToken,
packageInfo.getResDir(),
splitDirs,
packageInfo.getOverlayDirs(),
packageInfo.getApplicationInfo().sharedLibraryFiles,
displayId,
overrideConfiguration,
compatInfo,
classLoader));
context.mDisplay = resourcesManager.getAdjustedDisplay(displayId,
context.getResources());
return context;
}
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
createAppContext
メソッド:static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
null);
context.setResources(packageInfo.getResources());
return context;
}
以上、この
Activity
とService
とContext
とのつながりを調べてみました.