SystemUI起動プロセスと主体レイアウト紹介
http://www.jianshu.com/p/0ab1279465fa
本論文ではAndroid 6.0コードに基づいて、system UIの起動ローディングフローを分析し、system UIのいくつかのキービューのレイアウトと機能を紹介する.
一.SystemUI本体フレーム起動フロー
Androidデバイス上で電気的にブートをブートしてboot(通常はuboot)に入り、initramfs、ケネルミラーをロードして、ケネルを起動してから、ユーザー状態プログラムに入ります.最初のユーザ空間プログラムはinitで、PID固定は1.initの基本機能は以下の通りです.管理装置 Android起動スクリプトinit.rc を解析して処理する.は、このinit.rcのサービスをリアルタイムで維持し、Zygote をロードすることを含む.
ZygoteではSystemServerのコンポーネントを起動します.
本稿はSystemServerから分析を開始する.SystemServerはシステムサービスプロセスといい、Androidシステムを起動するキーサービスを担当しています.その入り口はSystem Server.mainです.
ここを見ると、system UIの本体フレームの起動フローをまとめられます.SystemServer起動AndroidコアサービスはActivityManagerService-->ActivityManagerSerServiceが起動されれば、systemUIcevice---SystemUIrviceを起動します.start()SystemUIの各種コアサービスを起動します.
二.SystemUIキービューの提示
携帯電話のドロップダウンステータスバー、ロックスクリーン、通知、および最近のジョブリストのオープンなどの機能は、SystemUIが実現しました.主な機能点に対応する画面は下図のようになります.
上記では、SystemUIの各サービスの起動プロセスを見ましたが、サービスができました.インターフェースビューはどのように現れますか?次にSystemBarsを例にとって、SystemUIの主要なビューである.上記のmServices[i].startはSystemBars.start()を呼び出します. ScrimView Phone Status BarView layout->status_bar Panel Holder id->Panel Holder ScrimView 実はここに重要なviewが漏れています.bouncerは直接にlayoutレイアウトに加入したのではなく、ユーザーがロックスクリーン保護を設定してからしか見えません.
Status BarWindowView
ここでは主にPhone Status BarView、Panel HolderとKeygurd Bouncerを調べます.
Phone Status BarViewは携帯電話の一番上の状態欄で、主にシステムの状態を表示するために用いられます.通知などは主にnotification iconsとstatus bar iconsを含みます.
Phone Status BarView
Panel Holder Panel Holderはユーザがstatus barを引いて得たviewです.それは主にQuickSettingsとNotification panelの二つの部分を含んでいます.Panel HolderはFrame Layoutから引き継がれたカスタムviewで、その内容はinclude statusを通じて(u)です.bar_expanded.xmlを充填します.Panel Holderはレイアウトが複雑で、viewの重用性を高めるためにincludeラベルを多く使いました.
Panel Holder
QuickSettings及びNotification panelインタフェースのレイアウト及び機能に関する文書はそれぞれQSPanel及びNotificationPanel Viewを修正する.
KeygurardBouncer KeygardBouncerは、スクリーンロック解除インターフェースであり、ユーザーが設定したロック解除方式によって異なるロック解除モードを示しています.まずKeygurard Bouncerの長さを見てください.
ロック画面:
Notification Keygard
スライドしてスクリーンをロックした後:
Keygurard Bouncer
注意したいのはKeygur dBouncerには様々な形があり、上の図には図の解錠が示されています.暗号解除のためにKeygurdBouncerがデジタルキーボードとして表示されます.いずれの形式もKeygurd Bouncerにロードされます.
Keygurard Bouncer
リボン:
SystemBarsのプレゼンテーションの流れを分析することによって、Phone Status BarView、Panel Holder、keygurdbouncerの3つのよくあるSystemUIのインターフェースレイアウトと関連機能を紹介しました.もちろん、SystemUIのレイアウトはまだ複雑で、上述は主要なビューだけを大きな方向から分析しました.SystemUIは、最近のアプリケーションビュー、ボトムナビゲーションバー、大域ボリューム管理Dialogなどのいくつかのレイアウトだけでなく、ここでは紹介されていません.
まとめ:
本論文は、SystemUI本体フレーム起動プロセスとSystemUIキービューのインターフェースレイアウト提示プロセスをそれぞれ2つの部分に分けて紹介する.以上の説明により、今後SystemUIに関する問題が発生した場合、まず問題Viewがどの大きな分類に属するかを特定し、次に図例に関連して提供されるidに関連して位置決め範囲を縮小することができる.
本論文ではAndroid 6.0コードに基づいて、system UIの起動ローディングフローを分析し、system UIのいくつかのキービューのレイアウトと機能を紹介する.
一.SystemUI本体フレーム起動フロー
Androidデバイス上で電気的にブートをブートしてboot(通常はuboot)に入り、initramfs、ケネルミラーをロードして、ケネルを起動してから、ユーザー状態プログラムに入ります.最初のユーザ空間プログラムはinitで、PID固定は1.initの基本機能は以下の通りです.
ZygoteではSystemServerのコンポーネントを起動します.
本稿はSystemServerから分析を開始する.SystemServerはシステムサービスプロセスといい、Androidシステムを起動するキーサービスを担当しています.その入り口はSystem Server.mainです.
/** * The main entry point from zygote. */
public static void main(String[] args) {
new SystemServer().run();
}
メールでSystemServerオブジェクトを生成してrunメソッドを実行したことが見られます.System Server.run():private void run() {
......
// Start services.
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
......
} catch (Throwable ex) {
...
throw ex;
}
...
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
まずstartBootstraphServicesを見ます. private void startBootstrapServices() {
......
Installer installer = mSystemServiceManager.startService(Installer.class);
// Activity manager runs the show.
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
......
}
startBootstraphServicesでmActivityManagerServiceが起動しました.その後、私たちは再びスターセットを見に行きます.private void startOtherServices() {
final Context context = mSystemContext;
AccountManagerService accountManager = null;
ContentService contentService = null;
.......
mActivityManagerService.systemReady(new Runnable() {
@Override
public void run() {
......
try {
startSystemUi(context);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
.......
mActivityManagerService.systemUiを実行するスレッドを作成します.方法名からも分かるように、ここでsystem UIが起動されます.static final void startSystemUi(Context context) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.OWNER);
}
intent.set Component(new ComponentName);systeemuiプログラムを起動するSystemUICServiceを設定してSystemUICServiceに入ります.public class SystemUIService extends Service {
@Override
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
}
......
onCreate方法ではSystemUIAppleオブジェクトを取得し、そのstartServices IfNeedメソッドを呼び出します. public void startServicesIfNeeded() {
final int N = SERVICES.length;
for (int i=0; i cl = SERVICES[i];
try {
mServices[i] = (SystemUI)cl.newInstance();//
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InstantiationException ex) {
throw new RuntimeException(ex);
}
mServices[i].mContext = this;
mServices[i].mComponents = mComponents;
mServices[i].start();//start
if (mBootCompleted) {
mServices[i].onBootCompleted();
}
}
mServicesStarted = true;
}
start Services IfNeed()循環startが多く見られます.配列SERVICESの定義は以下の通りである.private final Class>[] SERVICES = new Class[] {
com.android.systemui.tuner.TunerService.class, //
com.android.systemui.keyguard.KeyguardViewMediator.class,//
com.android.systemui.recents.Recents.class,//
com.android.systemui.volume.VolumeUI.class,//
com.android.systemui.statusbar.SystemBars.class,//
com.android.systemui.usb.StorageNotification.class,//Storage
com.android.systemui.power.PowerUI.class,//
com.android.systemui.media.RingtonePlayer.class,//
com.android.systemui.keyboard.KeyboardUI.class,//
};
サブサービスは、TunerService、KeygurdView Mediat、Recents、VolumeUI、SystemBars、StrageNotification、PowerUI Ringtone Player、KeyboardUIを含むことができます.でも、ここのサービスは私たちが普段話している四つのコンポーネントのサービスと違います.ここのサービスはSystemUI類の一般的な対象を継承しただけです.例えばSystemBars:public class SystemBars extends SystemUI implements ServiceMonitor.Callbacks {
......
}
リボン:ここを見ると、system UIの本体フレームの起動フローをまとめられます.SystemServer起動AndroidコアサービスはActivityManagerService-->ActivityManagerSerServiceが起動されれば、systemUIcevice---SystemUIrviceを起動します.start()SystemUIの各種コアサービスを起動します.
二.SystemUIキービューの提示
携帯電話のドロップダウンステータスバー、ロックスクリーン、通知、および最近のジョブリストのオープンなどの機能は、SystemUIが実現しました.主な機能点に対応する画面は下図のようになります.
上記では、SystemUIの各サービスの起動プロセスを見ましたが、サービスができました.インターフェースビューはどのように現れますか?次にSystemBarsを例にとって、SystemUIの主要なビューである.上記のmServices[i].startはSystemBars.start()を呼び出します.
@Override
public void start() {
if (DEBUG) Log.d(TAG, "start");
mServiceMonitor = new ServiceMonitor(TAG, DEBUG,
mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);
mServiceMonitor.start(); // will call onNoService if no remote service is found
}
startでServiceMonitorのインスタンスを作成してstart()を作成します.コメントでは、サービスが起動していない場合、ServiceMonitorはSystemBarsのオン・ノサーヴィスに戻ります.だからSystemBarsのオン・ノ・サービスを見に行きます. @Override
public void onNoService() {
if (DEBUG) Log.d(TAG, "onNoService");
createStatusBarFromConfig(); // fallback to using an in-process implementation
}
private void createStatusBarFromConfig() {
final String clsName = mContext.getString(R.string.config_statusBarComponent);
if (clsName == null || clsName.length() == 0) {
throw andLog("No status bar component configured", null);
}
Class> cls = null;
try {
cls = mContext.getClassLoader().loadClass(clsName);
} catch (Throwable t) {
throw andLog("Error loading status bar component: " + clsName, t);
}
try {
mStatusBar = (BaseStatusBar) cls.newInstance();
} catch (Throwable t) {
throw andLog("Error creating status bar component: " + clsName, t);
}
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mComponents;
mStatusBar.start();
}
CsNameで得られたstringはcomp.android.system.statusbar.phone.Phone Status BarでSystemBars.start()を実行した後、反射機構によって最終的にBaseStatus Barオブジェクトを得ることができます.ここで説明したいのは、BaseStatusBarはPhone Status Barの父類です.上記のmSttusBar.startはPhone Status Bar.startです. public void start() {
......
super.start(); // calls createAndAddWindows()
......
}
またBaseStartsBar.startに行きます.public void start() {
mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
mDisplay = mWindowManager.getDefaultDisplay();
mDevicePolicyManager = (DevicePolicyManager)mContext.getSystemService(
Context.DEVICE_POLICY_SERVICE);
mNotificationColorUtil = NotificationColorUtil.getInstance(mContext);
mNotificationData = new NotificationData(this);
mAccessibilityManager = (AccessibilityManager)
mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
mDreamManager = IDreamManager.Stub.asInterface(
ServiceManager.checkService(DreamService.DREAM_SERVICE));
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
.......
// systemui , ,Manager,Observer
.......
createAndAddWindows(); //
createAndAddWindowsを見る(): protected abstract void createAndAddWindows();
抽象的な方法です.明らかにBaseStatusBarのサブクラス、つまりPhone Status BarのcreateAndAddWindowsを呼び出しました. @Override
public void createAndAddWindows() {
addStatusBarWindow();
}
private void addStatusBarWindow() {
makeStatusBarView();// , StatusBarView
mStatusBarWindowManager = new StatusBarWindowManager(mContext);
mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
}
ポイントは、makeStatus BarViewを作成し、Status BarViewを作成し、その後、mStatus BarWindowManagerが追加し、ユーザーに提示するmakeStatus BarViewのコードは長いですが、主要コードはこの文です.protected PhoneStatusBarView makeStatusBarView()
{
......
mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
R.layout.super_status_bar, null);
......
}
super_を認識することによってstatusbar.xmlはSystemBarsの大体の構成を知ることができます.以下は部分省略のsuper_です.statusbarファイル
.android.systemui.statusbar.phone.StatusBarWindowView
android:fitsSystemWindows="true">
.android.systemui.statusbar.BackDropView
android:id="@+id/backdrop"
sysui:ignoreRightInset="true">
.android.systemui.statusbar.BackDropView>
.android.systemui.statusbar.ScrimView
android:id="@+id/scrim_behind"
android:importantForAccessibility="no"/>
.android.systemui.statusbar.AlphaOptimizedView
android:id="@+id/heads_up_scrim"
android:importantForAccessibility="no"/>
"@layout/status_bar"
android:layout_width="match_parent"
"@+id/brightness_mirror">
background="@drawable/brightness_mirror_background">
"@layout/quick_settings_brightness_dialog"
android:layout_height="wrap_content" />
.android.systemui.statusbar.phone.PanelHolder
android:id="@+id/panel_holder"
"@layout/status_bar_expanded"
android:visibility="gone" />
.android.systemui.statusbar.phone.PanelHolder>
.android.systemui.statusbar.ScrimView android:id="@+id/scrim_in_front"
android:importantForAccessibility="no"
sysui:ignoreRightInset="true"
/>
.android.systemui.statusbar.phone.StatusBarWindowView>
上記のviewレイアウト及びmakeStatus BarView関連コードにより、mStatus BarWindow(Status BarWindow View)には以下の4つの部分が含まれていることが分かります.Status BarWindowView
ここでは主にPhone Status BarView、Panel HolderとKeygurd Bouncerを調べます.
Phone Status BarViewは携帯電話の一番上の状態欄で、主にシステムの状態を表示するために用いられます.通知などは主にnotification iconsとstatus bar iconsを含みます.
Phone Status BarView
Panel Holder Panel Holderはユーザがstatus barを引いて得たviewです.それは主にQuickSettingsとNotification panelの二つの部分を含んでいます.Panel HolderはFrame Layoutから引き継がれたカスタムviewで、その内容はinclude statusを通じて(u)です.bar_expanded.xmlを充填します.Panel Holderはレイアウトが複雑で、viewの重用性を高めるためにincludeラベルを多く使いました.
Panel Holder
QuickSettings及びNotification panelインタフェースのレイアウト及び機能に関する文書はそれぞれQSPanel及びNotificationPanel Viewを修正する.
KeygurardBouncer KeygardBouncerは、スクリーンロック解除インターフェースであり、ユーザーが設定したロック解除方式によって異なるロック解除モードを示しています.まずKeygurard Bouncerの長さを見てください.
ロック画面:
Notification Keygard
スライドしてスクリーンをロックした後:
Keygurard Bouncer
注意したいのはKeygur dBouncerには様々な形があり、上の図には図の解錠が示されています.暗号解除のためにKeygurdBouncerがデジタルキーボードとして表示されます.いずれの形式もKeygurd Bouncerにロードされます.
public class KeyguardBouncer {
private ViewGroup mRoot;
private ViewGroup mContainer;
private KeyguardHostView mKeyguardView;
private void inflateView() {
mRoot = (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.keyguard_bouncer, null);
mKeyguardView =(KeyguardHostView)mRoot.findViewById(R.id.keyguard_host_view);
mKeyguardView.setLockPatternUtils(mLockPatternUtils);
mKeyguardView.setViewMediatorCallback(mCallback);
mContainer.addView(mRoot,mContainer.getChildCount());
}
KeygurardBouncerのViewツリーは以下の通りです.Keygurard Bouncer
リボン:
SystemBarsのプレゼンテーションの流れを分析することによって、Phone Status BarView、Panel Holder、keygurdbouncerの3つのよくあるSystemUIのインターフェースレイアウトと関連機能を紹介しました.もちろん、SystemUIのレイアウトはまだ複雑で、上述は主要なビューだけを大きな方向から分析しました.SystemUIは、最近のアプリケーションビュー、ボトムナビゲーションバー、大域ボリューム管理Dialogなどのいくつかのレイアウトだけでなく、ここでは紹介されていません.
まとめ:
本論文は、SystemUI本体フレーム起動プロセスとSystemUIキービューのインターフェースレイアウト提示プロセスをそれぞれ2つの部分に分けて紹介する.以上の説明により、今後SystemUIに関する問題が発生した場合、まず問題Viewがどの大きな分類に属するかを特定し、次に図例に関連して提供されるidに関連して位置決め範囲を縮小することができる.