Activity作成プロセス
30982 ワード
Activity作成プロセス分析
前の2つの記事では、デスクトップのアイコンをクリックしてプロセスを開始し、Activity Threadを起動してActivity ThreadにActivityを起動するプロセスの分析について述べた.Androidアプリケーション起動プロセス分析2.Activity Threadページ解析の開始
この文章は上の2つの文章に続いて、上述したActivity Thread performLaunchActivity()は、今日もここからActivityをどのように作成するかを続けています.
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
。。。
if (r.profileFd != null) {
mProfiler.setProfiler(r.profileFile, r.profileFd);
mProfiler.startProfiling();
mProfiler.autoStopProfiler = r.autoStopProfiler;
}
handleConfigurationChanged(null, null);
// , ActivityThread , Activity , , 。
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward);
。。。
} else {
try {
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null);
} catch (RemoteException ex) {
// Ignore
}
}
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
// Intent Activity
if (component == null) {
component = r.intent.resolveActivity(mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
Activity activity = null;
// mInstrumentation newActivity Activity
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
//ContextImpl ,
if (activity != null) {
ContextImpl appContext = new ContextImpl();
appContext.init(r.packageInfo, r.token, this);
appContext.setOuterContext(activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
// ,attach ?
// window WindowManagerService
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
// Activity onCreate 。
mInstrumentation.callActivityOnCreate(activity, r.state);
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
}
return activity;
}
上は簡単な注釈を与えて、すべて理解することができるべきで、それでは今明らかに最も重要なのはattachの方法の中で主に何をしたかを見てみます.
Instrumentation Activity
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
// , Activity
return (Activity)cl.loadClass(className).newInstance();
}
// Activity attach
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config) {
attachBaseContext(context);
mFragments.attachActivity(this);
// API——15 , 。
// Window WindowManager
mWindow = PolicyManager.makeNewWindow(this);
// public Window makeNewWindow(Context context) {
// return new PhoneWindow(context);
//}
mWindow.setCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
mWindow.setSoftInputMode(info.softInputMode);
}
if (info.uiOptions != 0) {
mWindow.setUiOptions(info.uiOptions);
}
mUiThread = Thread.currentThread();
mMainThread = aThread;
mInstrumentation = instr;
mToken = token;
mIdent = ident;
mApplication = application;
mIntent = intent;
mComponent = intent.getComponent();
mActivityInfo = info;
mTitle = title;
mParent = parent;
mEmbeddedID = id;
mLastNonConfigurationInstances = lastNonConfigurationInstances;
mWindow.setWindowManager(null, mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
mWindowManager = mWindow.getWindowManager();
mCurrentConfig = config;
}
今日の内容はとても簡単で、私たちはActivity Threadの中でActivity Management Service、H、ApplicationThreadの操作を通じて最終的にperformLaunchActivityに着いて、Instrumentation呼び出し反射を通じてActivityのオブジェクトを得て、それからWindowを作成してonCreate方法を呼び出して、それでは私たちはonCreate方法の中で私たちが一般的に何を書いているか知っていますか?setContentView()ではないでしょうか.つまり、本格的な描画の道が始まったのです.描画の道のりにはWindowManagerServiceが欠かせないのではないでしょうか.上にはWindowが作成されています.もう近いようです.いいえ、今日はここまでです.次はActivityの描画の流れを見てみましょう.