Android 4.2 SetContentViewプロセス分析(一)
11418 ワード
startActivityを呼び出して新しいActivityを起動すると、System ServerはSocketを介してZygoteに要求を送信し、この要求には「android.app.Activity Thread」パラメータがある.Zygoteは、このリクエストによりforkのサブプロセス(起動したactivityが属するプロセスがまだ起動していないと仮定)を実行し、このサブプロセスがAppに対応するプロセスである.このエントリ関数がActivity Threadのmain functionである.
Activity Thread classにはfunction handleLaunchActivityがあり、handleLaunchActivityの機能はActivityを追加する場所であり、main functionがhandleLaunchActivity functionにどのように呼び出すかのプロセス分析は今回の分析ではないので、handleLaunchActivityという関数を直接見てみましょう.
(1)
onCreate functionは、このfunctionで利用されます
setContentViewはUIインタフェースを設定する.
getWindow().setContentView(view); この行のプログラムコードには2つの役割があります.WindowとViewです.SDKの記述によるWindowとViewの定義は以下の通りである.
Window
Abstract base class for a top-level window look andbehavior policy. An instance of this class should be used as the top-level viewadded to the window manager. It provides standard UI policies such as abackground, title area, default key processing, etc.
Windowは抽象クラスであり、主にtop windowの外観と動作、すなわちUIコンポーネントの描画とデフォルトの入力処理を制御するために使用される.
View
This class represents the basic building block foruser interface components. A View occupies a rectangular area on the screen andis responsible for drawing and event handling
ビューは画面の矩形を基本的に占有するUIユニットであり、絵画やイベントの処理に用いることができる.
getWindow回送のwindow物件は何ですか?setContentViewのViewオブジェクトは何を表していますか?次のように分析されます.
1.getWindow回送window物件.
8つ目のステップでは、新しく生成するアプリケーションに新しいactivityを埋め込む、mWindowオブジェクトはこのときに生成される.直接的に見ると
8番目のステップで呼び出されたactivity.
attach関数の実作
PolicyManager.makeNewWindowは新しいWindowオブジェクトを作成し、新しいWindowオブジェクトをWindowManagerロールに設定します.
新しいウィンドウのアイテムは何ですか?
1. mWindow = PolicyManager.makeNewWindow(this);
==> mWindow = new PhoneWindow(this);
2. mWindow.setWindowManager
==> new PhoneWindow(this). setWindowManager
WindowManagerは何ですか?
本来はmWindowがPhoneWindowのオブジェクトである以上、PhoneWindowカテゴリに行ってsetWindowManager functionの実作を探してみたが、見つからなかった.
それからPhoneWindowの親カテゴリWindowに行って探しました.
WindowManagerは
WindowManagerImplオブジェクト
2.setContentViewのビューアイテム
前述の解析から、getWindowから伝わるmWindowはPhoneWindowオブジェクトであることが分かるので、PhoneWindowカテゴリから分析することができる.
から
setContentView
関数の2番目のステップ
わかる
,setContentView
の中
View
オブジェクトは
DecoreView (ViewGroup)
の子
View.
ここで結論を出します.performLaunchActivity関数でmInstrumentationを呼び出します.callActivity OnCreateは、次にActivityのonCreate functionをトリガし、一般的にonCreateで最初にsetContentViewを利用してUIコンポーネントを設定する.setContentViewこの関数はPhoneWindow,WindowManagerImpl,DecoreViewの3つのUI関連オブジェクトを持ち出す.
1.getWindowは、PhoneWindowオブジェクトであるmWindowを得る.
2.PhoneWindowオブジェクトを利用してWindowManagerImplの役割を設定.
3.PhoneWindow物件はDecoreViewのサブビューを設定する.
Activity Thread classにはfunction handleLaunchActivityがあり、handleLaunchActivityの機能はActivityを追加する場所であり、main functionがhandleLaunchActivity functionにどのように呼び出すかのプロセス分析は今回の分析ではないので、handleLaunchActivityという関数を直接見てみましょう.
[ActivityThread.java]
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//...
// Activity . UI ( View,
//Window.)
Activity a = performLaunchActivity(r, customIntent); (1)
if (a != null) {
//...
// ViewRootImpl WindowManagerService, Surface
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed); (2)
if (!r.activity.mFinished && r.startsNotResumed) {
// Activity visible , Activity
//Manager Service Activity Pause state.
}
} else {
// Activity Manager Service Activity.
}
}
(1)
[ActivityThread.java]
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//1. ActivityClientRecord package information,
// Apk package information.
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
//2. ActivityClientRecord component,
// ActivityClientRecord intent component .
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
//3. Package information ComponentName
// .
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
Activity activity = null;
try {
//4. ActivityClientRecord package information Class
//Loader.
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
//5. Class loader ComponentName
//mInstrumentation.newActivity activity .
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
//...
} catch (Exception e) {
//...
}
try {
//6. ActivityClientRecord package information
// Application.
Application app = r.packageInfo.makeApplication(false,
mInstrumentation);
if (activity != null) {
//7. Activity context .
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title =
r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new
Configuration(mCompatConfiguration);
//8. Activity Application.
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances,
config);
//9. activity intent
if (customIntent != null) {
activity.mIntent = customIntent;
}
//...
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
//...
//10. Activity Create state.
activity.mCalled = false;
mInstrumentation.callActivityOnCreate(activity, r.state);
}
//...
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
//...
}
return activity;
}
これまで、新しいActivityが起動されたときに、最初に呼び出されるのはonCreate functionは、このfunctionで利用されます
setContentViewはUIインタフェースを設定する.
[Activity.java]
public void setContentView(View view) {
// Window UI .
getWindow().setContentView(view);
// android 4.x UI , UI
// . , .
initActionBar();
}
getWindow().setContentView(view); この行のプログラムコードには2つの役割があります.WindowとViewです.SDKの記述によるWindowとViewの定義は以下の通りである.
Window
Abstract base class for a top-level window look andbehavior policy. An instance of this class should be used as the top-level viewadded to the window manager. It provides standard UI policies such as abackground, title area, default key processing, etc.
Windowは抽象クラスであり、主にtop windowの外観と動作、すなわちUIコンポーネントの描画とデフォルトの入力処理を制御するために使用される.
View
This class represents the basic building block foruser interface components. A View occupies a rectangular area on the screen andis responsible for drawing and event handling
ビューは画面の矩形を基本的に占有するUIユニットであり、絵画やイベントの処理に用いることができる.
getWindow回送のwindow物件は何ですか?setContentViewのViewオブジェクトは何を表していますか?次のように分析されます.
1.getWindow回送window物件.
[Activity.java]
public Window getWindow() {
return mWindow;
}
mWindowとは何か、これはactivityを追加したperformLaunchActivity functionから始める必要があります.performLaunchActivity functionを先に分析したところ、performLaunchActivityの8つ目のステップでは、新しく生成するアプリケーションに新しいactivityを埋め込む、mWindowオブジェクトはこのときに生成される.直接的に見ると
8番目のステップで呼び出されたactivity.
attach関数の実作
[Activity.java]
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) {
//...
mWindow = PolicyManager.makeNewWindow(this);
//...
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken,
mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) !=
0);
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
mWindowManager = mWindow.getWindowManager();
mCurrentConfig = config;
}
ここの肝心な動作は2つのことをして、まずPolicyManager.makeNewWindowは新しいWindowオブジェクトを作成し、新しいWindowオブジェクトをWindowManagerロールに設定します.
新しいウィンドウのアイテムは何ですか?
[PolicyManager.java]
public static Window makeNewWindow(Context context) {
//sPolicy IPolicy , IPolicy .
return sPolicy.makeNewWindow(context);
}
[Policy.java]
public Window makeNewWindow(Context context) {
// Window PhoneWindow .
return new PhoneWindow(context);
}
以上の分析から以下の推論が得られる.1. mWindow = PolicyManager.makeNewWindow(this);
==> mWindow = new PhoneWindow(this);
2. mWindow.setWindowManager
==> new PhoneWindow(this). setWindowManager
WindowManagerは何ですか?
本来はmWindowがPhoneWindowのオブジェクトである以上、PhoneWindowカテゴリに行ってsetWindowManager functionの実作を探してみたが、見つからなかった.
それからPhoneWindowの親カテゴリWindowに行って探しました.
[Window.java]
public void setWindowManager(WindowManager wm, IBinder appToken, String appName, boolean hardwareAccelerated) {
mAppToken = appToken;
mAppName = appName;
mHardwareAccelerated = hardwareAccelerated
|| SystemProperties.getBoolean(PROPERTY_HARDWARE_UI,
false);
if (wm == null) {
//1. ServiceManger Window Manger service proxy.
wm =
(WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
}
//2. Window Manger service proxy WindowManager.
mWindowManager =
((WindowManagerImpl)wm).createLocalWindowManager(this);
}
[WindowManagerImpl.java]
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
return new WindowManagerImpl(mDisplay, parentWindow);
}
以上の分析から分かるWindowManagerは
WindowManagerImplオブジェクト
2.setContentViewのビューアイテム
前述の解析から、getWindowから伝わるmWindowはPhoneWindowオブジェクトであることが分かるので、PhoneWindowカテゴリから分析することができる.
[PhoneWindow.java]
@Override
public void setContentView(View view) {
//
setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT,
MATCH_PARENT));
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
//1. mContentParent ViewGroup , null.
if (mContentParent == null) {
// DecoreView,
installDecor();
} else {
mContentParent.removeAllViews();
}
//2. View mContentParent (DecoreView) .
mContentParent.addView(view, params);
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
}
private void installDecor() {
if (mDecor == null) {
//DecorView , FrameLayout .
mDecor = generateDecor();
//...
}
if (mContentParent == null) {
//
mContentParent = generateLayout(mDecor);
//...
} else {
//...
}
}
}
protected ViewGroup generateLayout(DecorView decor) {
//...
View in = mLayoutInflater.inflate(layoutResource, null);
// ViewGroup LayoutParams DecoreView
decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT,
MATCH_PARENT));
// findViewById ID_ANDROID_CONTENT ViewGroup
// .
ViewGroup contentParent =
(ViewGroup)findViewById(ID_ANDROID_CONTENT);
//...
retrun contentParent;
}
から
setContentView
関数の2番目のステップ
わかる
,setContentView
の中
View
オブジェクトは
DecoreView (ViewGroup)
の子
View.
ここで結論を出します.performLaunchActivity関数でmInstrumentationを呼び出します.callActivity OnCreateは、次にActivityのonCreate functionをトリガし、一般的にonCreateで最初にsetContentViewを利用してUIコンポーネントを設定する.setContentViewこの関数はPhoneWindow,WindowManagerImpl,DecoreViewの3つのUI関連オブジェクトを持ち出す.
1.getWindowは、PhoneWindowオブジェクトであるmWindowを得る.
2.PhoneWindowオブジェクトを利用してWindowManagerImplの役割を設定.
3.PhoneWindow物件はDecoreViewのサブビューを設定する.