android SystemUi學(xué)習(xí)筆記

SystemUI 是如何啟動(dòng)的

systemui包括了系統(tǒng)欄和導(dǎo)航欄呢燥,也就是我們看到的電量崭添、時(shí)間欄和返回按鍵這類(lèi)的導(dǎo)航欄。systemui也是一個(gè)apk叛氨,所以我們就會(huì)想他是如何啟動(dòng)的呢呼渣,
android 系統(tǒng)的啟動(dòng)肯定是首先 systemserver, systemserver會(huì)啟動(dòng)android 系統(tǒng)所需的各種服務(wù),比如activtymanagerservice寞埠,當(dāng)mActivityManagerService的systemReady回調(diào)后就會(huì)執(zhí)行 啟動(dòng)systemui的動(dòng)作屁置。

ActivityManagerService 的systemReady

    public void systemReady(final Runnable goingCallback) {
        synchronized(this) {
            if (mSystemReady) {
                // If we're done calling all the receivers, run the next "boot phase" passed in
                // by the SystemServer
                if (goingCallback != null) {
                    goingCallback.run();
                }
                return;
            }

            mLocalDeviceIdleController
                    = LocalServices.getService(DeviceIdleController.LocalService.class);

            // Make sure we have the current profile info, since it is needed for
            // security checks.
            updateCurrentProfileIdsLocked();

            mRecentTasks.clear();
            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
            mTaskPersister.startPersisting();

            // Check to see if there are any update receivers to run.
            if (!mDidUpdate) {
                if (mWaitingUpdate) {
                    return;
                }
                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
                    public void run() {
                        synchronized (ActivityManagerService.this) {
                            mDidUpdate = true;
                        }
                        showBootMessage(mContext.getText(
                                R.string.android_upgrading_complete),
                                false);
                        writeLastDonePreBootReceivers(doneReceivers);
                       systemReady(goingCallback); //這里調(diào)到了調(diào)到了 SystemServer 里面設(shè)置的回調(diào)。啟動(dòng)systemui 
                    }
                }, doneReceivers, UserHandle.USER_OWNER);

                if (mWaitingUpdate) {
                    return;
                }
                mDidUpdate = true;
            }

            mAppOpsService.systemReady();
            mSystemReady = true;
        }

        ArrayList<ProcessRecord> procsToKill = null;
        synchronized(mPidsSelfLocked) {
            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
                if (!isAllowedWhileBooting(proc.info)){
                    if (procsToKill == null) {
                        procsToKill = new ArrayList<ProcessRecord>();
                    }
                    procsToKill.add(proc);
                }
            }
        }

        synchronized(this) {
            if (procsToKill != null) {
                for (int i=procsToKill.size()-1; i>=0; i--) {
                    ProcessRecord proc = procsToKill.get(i);
                    Slog.i(TAG, "Removing system update proc: " + proc);
                    removeProcessLocked(proc, true, false, "system update done");
                }
            }

            // Now that we have cleaned up any update processes, we
            // are ready to start launching real processes and know that
            // we won't trample on them any more.
            mProcessesReady = true;
        }

        Slog.i(TAG, "System now ready");
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
            SystemClock.uptimeMillis());

        synchronized(this) {
            // Make sure we have no pre-ready processes sitting around.

            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
                ResolveInfo ri = mContext.getPackageManager()
                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
                                STOCK_PM_FLAGS);
                CharSequence errorMsg = null;
                if (ri != null) {
                    ActivityInfo ai = ri.activityInfo;
                    ApplicationInfo app = ai.applicationInfo;
                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
                        mTopAction = Intent.ACTION_FACTORY_TEST;
                        mTopData = null;
                        mTopComponent = new ComponentName(app.packageName,
                                ai.name);
                    } else {
                        errorMsg = mContext.getResources().getText(
                                com.android.internal.R.string.factorytest_not_system);
                    }
                } else {
                    errorMsg = mContext.getResources().getText(
                            com.android.internal.R.string.factorytest_no_action);
                }
                if (errorMsg != null) {
                    mTopAction = null;
                    mTopData = null;
                    mTopComponent = null;
                    Message msg = Message.obtain();
                    msg.what = SHOW_FACTORY_ERROR_MSG;
                    msg.getData().putCharSequence("msg", errorMsg);
                    mUiHandler.sendMessage(msg);
                }
            }
        }

        retrieveSettings();
        loadResourcesOnSystemReady();

        synchronized (this) {
            readGrantedUriPermissionsLocked();
        }

        if (goingCallback != null) goingCallback.run();

        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
                Integer.toString(mCurrentUserId), mCurrentUserId);
        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
                Integer.toString(mCurrentUserId), mCurrentUserId);
        mSystemServiceManager.startUser(mCurrentUserId);

        synchronized (this) {
            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
                try {
                    List apps = AppGlobals.getPackageManager().
                        getPersistentApplications(STOCK_PM_FLAGS);
                    if (apps != null) {
                        int N = apps.size();
                        int i;
                        for (i=0; i<N; i++) {
                            ApplicationInfo info
                                = (ApplicationInfo)apps.get(i);
                            if (info != null &&
                                    !info.packageName.equals("android")) {
                                addAppLocked(info, false, null /* ABI override */);
                            }
                        }
                    }
                } catch (RemoteException ex) {
                    // pm is in same process, this will never happen.
                }
            }

            // Start up initial activity.
            mBooting = true;
            startHomeActivityLocked(mCurrentUserId, "systemReady"); //這里啟動(dòng)launcher 應(yīng)用仁连,所以 systemui 是在launcher之前啟動(dòng)

            try {
                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
                            + " data partition or your device will be unstable.");
                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
                }
            } catch (RemoteException e) {
            }

            if (!Build.isBuildConsistent()) {
                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
            }

            long ident = Binder.clearCallingIdentity();
            try {
                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                        | Intent.FLAG_RECEIVER_FOREGROUND);
                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
                broadcastIntentLocked(null, null, intent,
                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
                        null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
                intent = new Intent(Intent.ACTION_USER_STARTING);
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
                broadcastIntentLocked(null, null, intent,
                        null, new IIntentReceiver.Stub() {
                            @Override
                            public void performReceive(Intent intent, int resultCode, String data,
                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
                                    throws RemoteException {
                            }
                        }, 0, null, null,
                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
            } catch (Throwable t) {
                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
            mStackSupervisor.resumeTopActivitiesLocked();
            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
        }
    }

SystemServer 當(dāng)中

// These are needed to propagate to the runnable below.
        final NetworkManagementService networkManagementF = networkManagement;
        final NetworkStatsService networkStatsF = networkStats;
        final NetworkPolicyManagerService networkPolicyF = networkPolicy;
        final ConnectivityService connectivityF = connectivity;
        final NetworkScoreService networkScoreF = networkScore;
        final WallpaperManagerService wallpaperF = wallpaper;
        final InputMethodManagerService immF = imm;
        final LocationManagerService locationF = location;
        final CountryDetectorService countryDetectorF = countryDetector;
        final NetworkTimeUpdateService networkTimeUpdaterF = networkTimeUpdater;
        final CommonTimeManagementService commonTimeMgmtServiceF = commonTimeMgmtService;
        final TextServicesManagerService textServiceManagerServiceF = tsms;
        final StatusBarManagerService statusBarF = statusBar;
        final AssetAtlasService atlasF = atlas;
        final InputManagerService inputManagerF = inputManager;
        final TelephonyRegistry telephonyRegistryF = telephonyRegistry;
        final MediaRouterService mediaRouterF = mediaRouter;
        final AudioService audioServiceF = audioService;
        final MmsServiceBroker mmsServiceF = mmsService;

        // We now tell the activity manager it is okay to run third party
        // code.  It will call back into us once it has gotten to the state
        // where third party code can really run (but before it has actually
        // started launching the initial applications), for us to complete our
        // initialization.
        mActivityManagerService.systemReady(new Runnable() {
            @Override
            public void run() {
                Slog.i(TAG, "Making services ready");
                mSystemServiceManager.startBootPhase(
                        SystemService.PHASE_ACTIVITY_MANAGER_READY);

                try {
                    mActivityManagerService.startObservingNativeCrashes();
                } catch (Throwable e) {
                    reportWtf("observing native crashes", e);
                }

                Slog.i(TAG, "WebViewFactory preparation");
                WebViewFactory.prepareWebViewInSystemServer();

                try {
                    startSystemUi(context); //啟動(dòng)SystemUi
                } catch (Throwable e) {
                    reportWtf("starting System UI", e);
                }
                try {
                    if (networkScoreF != null) networkScoreF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Network Score Service ready", e);
                }
                try {
                    if (networkManagementF != null) networkManagementF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Network Managment Service ready", e);
                }
                try {
                    if (networkStatsF != null) networkStatsF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Network Stats Service ready", e);
                }
                try {
                    if (networkPolicyF != null) networkPolicyF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Network Policy Service ready", e);
                }
                try {
                    if (connectivityF != null) connectivityF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Connectivity Service ready", e);
                }
                try {
                    if (audioServiceF != null) audioServiceF.systemReady();
                } catch (Throwable e) {
                    reportWtf("Notifying AudioService running", e);
                }
                Watchdog.getInstance().start();

                // It is now okay to let the various system services start their
                // third party code...
                mSystemServiceManager.startBootPhase(
                        SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);

                try {
                    if (wallpaperF != null) wallpaperF.systemRunning();
                } catch (Throwable e) {
                    reportWtf("Notifying WallpaperService running", e);
                }
                try {
                    if (immF != null) immF.systemRunning(statusBarF);
                } catch (Throwable e) {
                    reportWtf("Notifying InputMethodService running", e);
                }
                try {
                    if (locationF != null) locationF.systemRunning();
                } catch (Throwable e) {
                    reportWtf("Notifying Location Service running", e);
                }
                try {
                    if (countryDetectorF != null) countryDetectorF.systemRunning();
                } catch (Throwable e) {
                    reportWtf("Notifying CountryDetectorService running", e);
                }
                try {
                    if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemRunning();
                } catch (Throwable e) {
                    reportWtf("Notifying NetworkTimeService running", e);
                }
                try {
                    if (commonTimeMgmtServiceF != null) {
                        commonTimeMgmtServiceF.systemRunning();
                    }
                } catch (Throwable e) {
                    reportWtf("Notifying CommonTimeManagementService running", e);
                }
                try {
                    if (textServiceManagerServiceF != null)
                        textServiceManagerServiceF.systemRunning();
                } catch (Throwable e) {
                    reportWtf("Notifying TextServicesManagerService running", e);
                }
                try {
                    if (atlasF != null) atlasF.systemRunning();
                } catch (Throwable e) {
                    reportWtf("Notifying AssetAtlasService running", e);
                }
                try {
                    // TODO(BT) Pass parameter to input manager
                    if (inputManagerF != null) inputManagerF.systemRunning();
                } catch (Throwable e) {
                    reportWtf("Notifying InputManagerService running", e);
                }
                try {
                    if (telephonyRegistryF != null) telephonyRegistryF.systemRunning();
                } catch (Throwable e) {
                    reportWtf("Notifying TelephonyRegistry running", e);
                }
                try {
                    if (mediaRouterF != null) mediaRouterF.systemRunning();
                } catch (Throwable e) {
                    reportWtf("Notifying MediaRouterService running", e);
                }

                try {
                    if (mmsServiceF != null) mmsServiceF.systemRunning();
                } catch (Throwable e) {
                    reportWtf("Notifying MmsService running", e);
                }
            }
        });
    }
//啟動(dòng)了 systemui package里面的SystemUIService
 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);
    }```

###  systemui 中運(yùn)行了哪些服務(wù)蓝角?
直接看看 systemuiservice里面代碼

package com.android.systemui;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

import java.io.FileDescriptor;
import java.io.PrintWriter;

public class SystemUIService extends Service {

@Override
public void onCreate() {
    super.onCreate();
    ((SystemUIApplication) getApplication()).startServicesIfNeeded(); // 只是做了這件事情
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    SystemUI[] services = ((SystemUIApplication) getApplication()).getServices();
    if (args == null || args.length == 0) {
        for (SystemUI ui: services) {
            pw.println("dumping service: " + ui.getClass().getName());
            ui.dump(fd, pw, args);
        }
    } else {
        String svc = args[0];
        for (SystemUI ui: services) {
            String name = ui.getClass().getName();
            if (name.endsWith(svc)) {
                ui.dump(fd, pw, args);
            }
        }
    }
}

}


走到了 SystemUIApplication 里面

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,
com.android.systemui.power.PowerUI.class,
com.android.systemui.media.RingtonePlayer.class,
};

public void startServicesIfNeeded() {
if (mServicesStarted) {
return;
}

    if (!mBootCompleted) {
        // check to see if maybe it was already completed long before we began
        // see ActivityManagerService.finishBooting()
        if ("1".equals(SystemProperties.get("sys.boot_completed"))) {
            mBootCompleted = true;
            if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent");
        }
    }

    Log.v(TAG, "Starting SystemUI services.");
    final int N = SERVICES.length;
    for (int i=0; i<N; i++) {
        Class<?> cl = SERVICES[i];
        if (DEBUG) Log.d(TAG, "loading: " + cl);
        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;
        if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
        mServices[i].start();

        if (mBootCompleted) {
            mServices[i].onBootCompleted();
        }
    }
    mServicesStarted = true;
}
以上看以看出分別啟動(dòng)了  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,
            com.android.systemui.power.PowerUI.class,
            com.android.systemui.media.RingtonePlayer.class,
這些子服務(wù),它自己?jiǎn)?dòng)沒(méi)有干什么事情怖糊。

### systemui的那些ui布局是在哪里被顯示出來(lái)的 帅容?
帶著這個(gè)問(wèn)題 看看com.android.systemui.statusbar.SystemBars.class 這個(gè)的實(shí)現(xiàn),
SystemBars.java 中啟動(dòng)

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
}

再繼續(xù)跟進(jìn)ServiceMonitor.java  的start

public void start() {
// listen for setting changes
ContentResolver cr = mContext.getContentResolver();
cr.registerContentObserver(Settings.Secure.getUriFor(mSettingKey),
false /notifyForDescendents/, mSettingObserver, UserHandle.USER_ALL);

    // listen for package/component changes
    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_PACKAGE_ADDED);
    filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
    filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
    filter.addDataScheme("package");
    mContext.registerReceiver(mBroadcastReceiver, filter)

    mHandler.sendEmptyMessage(MSG_START_SERVICE);
}
上面注冊(cè)了一個(gè)setting數(shù)據(jù)庫(kù)的監(jiān)聽(tīng)器和package change的廣播伍伤,然而這個(gè)不是我們現(xiàn)在關(guān)心的并徘,看到最后 mHandler有發(fā)送一個(gè)消息出去MSG_START_SERVICE。又啟動(dòng)了一個(gè)服務(wù)扰魂?繼續(xù)看吧

private final Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch(msg.what) {
case MSG_START_SERVICE:
startService();
break;
case MSG_CONTINUE_START_SERVICE:
continueStartService();
break;
case MSG_STOP_SERVICE:
stopService();
break;
case MSG_PACKAGE_INTENT:
packageIntent((Intent)msg.obj);
break;
case MSG_CHECK_BOUND:
checkBound();
break;
case MSG_SERVICE_DISCONNECTED:
serviceDisconnected((ComponentName)msg.obj);
break;
}
}
};

private void startService() {
mServiceName = getComponentNameFromSetting();
if (mDebug) Log.d(mTag, "startService mServiceName=" + mServiceName);
if (mServiceName == null) {
mBound = false; //走到了這個(gè)分支
mCallbacks.onNoService();
} else {
long delay = mCallbacks.onServiceStartAttempt();
mHandler.sendEmptyMessageDelayed(MSG_CONTINUE_START_SERVICE, delay);
}
}

public interface Callbacks {
/** The service does not exist or failed to bind /
void onNoService();
/
* The service is about to start, this is a chance to perform cleanup and
* delay the start if necessary */
long onServiceStartAttempt();
}

可見(jiàn) Callbacks  這個(gè)回調(diào)是在實(shí)現(xiàn)的地方來(lái)執(zhí)行的麦乞,實(shí)現(xiàn)了它的地方在SystemBars.java

@Override
public void onNoService() {
if (DEBUG) Log.d(TAG, "onNoService");
//這里開(kāi)始創(chuàng)建statusbar了
createStatusBarFromConfig(); // fallback to using an in-process implementation
}

@Override
public long onServiceStartAttempt() {
    if (DEBUG) Log.d(TAG, "onServiceStartAttempt mStatusBar="+mStatusBar);
    if (mStatusBar != null) {
        // tear down the in-process version, we'll recreate it again if needed
        mStatusBar.destroy();
        mStatusBar = null;
        return WAIT_FOR_BARS_TO_DIE;
    }
    return 0;
}

// in-process fallback implementation, per the product config
private BaseStatusBar mStatusBar;

private void createStatusBarFromConfig() {
if (DEBUG) Log.d(TAG, "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();
if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
}

下面就要正在把view相關(guān)的內(nèi)容添加進(jìn)來(lái)了BaseStatusBar 的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);

    mContext.getContentResolver().registerContentObserver(
            Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), true,
            mSettingsObserver);
    mContext.getContentResolver().registerContentObserver(
            Settings.Global.getUriFor(Settings.Global.ZEN_MODE), false,
            mSettingsObserver);
    mContext.getContentResolver().registerContentObserver(
            Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS), false,
            mSettingsObserver,
            UserHandle.USER_ALL);

    mContext.getContentResolver().registerContentObserver(
            Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
            true,
            mLockscreenSettingsObserver,
            UserHandle.USER_ALL);

    mBarService = IStatusBarService.Stub.asInterface(
            ServiceManager.getService(Context.STATUS_BAR_SERVICE));

    mRecents = getComponent(Recents.class);
    mRecents.setCallback(this);

    final Configuration currentConfig = mContext.getResources().getConfiguration();
    mLocale = currentConfig.locale;
    mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(mLocale);
    mFontScale = currentConfig.fontScale;

    mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);

    mLinearOutSlowIn = AnimationUtils.loadInterpolator(mContext,
            android.R.interpolator.linear_out_slow_in);
    mFastOutLinearIn = AnimationUtils.loadInterpolator(mContext,
            android.R.interpolator.fast_out_linear_in);

    // Connect in to the status bar manager service
    StatusBarIconList iconList = new StatusBarIconList();
    mCommandQueue = new CommandQueue(this, iconList);

    int[] switches = new int[8];
    ArrayList<IBinder> binders = new ArrayList<IBinder>();
    try {
        mBarService.registerStatusBar(mCommandQueue, iconList, switches, binders);
    } catch (RemoteException ex) {
        // If the system process isn't there we're doomed anyway.
    }

    createAndAddWindows();//創(chuàng)建view 

    mSettingsObserver.onChange(false); // set up
    disable(switches[0], switches[6], false /* animate */);
    setSystemUiVisibility(switches[1], 0xffffffff);
    topAppWindowChanged(switches[2] != 0);
    // StatusBarManagerService has a back up of IME token and it's restored here.
    setImeWindowStatus(binders.get(0), switches[3], switches[4], switches[5] != 0);

    // Set up the initial icon state
    int N = iconList.size();
    int viewIndex = 0;
    for (int i=0; i<N; i++) {
        StatusBarIcon icon = iconList.getIcon(i);
        if (icon != null) {
            addIcon(iconList.getSlot(i), i, viewIndex, icon);
            viewIndex++;
        }
    }

    // Set up the initial notification state.
    try {
        mNotificationListener.registerAsSystemService(mContext,
                new ComponentName(mContext.getPackageName(), getClass().getCanonicalName()),
                UserHandle.USER_ALL);
    } catch (RemoteException e) {
        Log.e(TAG, "Unable to register notification listener", e);
    }


    if (DEBUG) {
        Log.d(TAG, String.format(
                "init: icons=%d disabled=0x%08x lights=0x%08x menu=0x%08x imeButton=0x%08x",
               iconList.size(),
               switches[0],
               switches[1],
               switches[2],
               switches[3]
               ));
    }

    mCurrentUserId = ActivityManager.getCurrentUser();
    setHeadsUpUser(mCurrentUserId);

    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_USER_SWITCHED);
    filter.addAction(Intent.ACTION_USER_ADDED);
    filter.addAction(Intent.ACTION_USER_PRESENT);
    filter.addAction(BANNER_ACTION_CANCEL);
    filter.addAction(BANNER_ACTION_SETUP);
    mContext.registerReceiver(mBroadcastReceiver, filter);

    IntentFilter allUsersFilter = new IntentFilter();
    allUsersFilter.addAction(
            DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
    mContext.registerReceiverAsUser(mAllUsersReceiver, UserHandle.ALL, allUsersFilter,
            null, null);
    updateCurrentProfilesCache();
}
可以從源碼中看到     protected abstract void createAndAddWindows(); 是一個(gè)抽象方法,所以這個(gè)應(yīng)該是由它的子類(lèi)來(lái)進(jìn)行實(shí)現(xiàn)的劝评,PhoneStatusBar.java 中找到了它的實(shí)現(xiàn)姐直。

@Override
public void createAndAddWindows() {
addStatusBarWindow();
}

private void addStatusBarWindow() {
    makeStatusBarView();// 加載view
    mStatusBarWindowManager = new StatusBarWindowManager(mContext);
    mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
}


// ================================================================================
// Constructing the view
// ================================================================================
protected PhoneStatusBarView makeStatusBarView() {
    final Context context = mContext;

    Resources res = context.getResources();

    updateDisplaySize(); // populates mDisplayMetrics
    updateResources();

    mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
            R.layout.super_status_bar, null); // view的布局文件
    mStatusBarWindow.setService(this);
    mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            checkUserAutohide(v, event);
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                if (mExpandedVisible) {
                    animateCollapsePanels();
                }
            }
            return mStatusBarWindow.onTouchEvent(event);
        }
    });

    mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
    mStatusBarView.setBar(this);

    PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder);
    mStatusBarView.setPanelHolder(holder);

    mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
            R.id.notification_panel);
    mNotificationPanel.setStatusBar(this);

    if (!ActivityManager.isHighEndGfx()) {
        mStatusBarWindow.setBackground(null);
        mNotificationPanel.setBackground(new FastColorDrawable(context.getColor(
                R.color.notification_panel_solid_background)));
    }

    mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow);
    mHeadsUpManager.setBar(this);
    mHeadsUpManager.addListener(this);
    mHeadsUpManager.addListener(mNotificationPanel);
    mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
    mNotificationData.setHeadsUpManager(mHeadsUpManager);

    if (MULTIUSER_DEBUG) {
        mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(
                R.id.header_debug_info);
        mNotificationPanelDebugText.setVisibility(View.VISIBLE);
    }

    try {
        boolean showNav = mWindowManagerService.hasNavigationBar();
        if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
        if (showNav) {
            mNavigationBarView =
                (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);

            mNavigationBarView.setDisabledFlags(mDisabled1);
            mNavigationBarView.setBar(this);
            mNavigationBarView.setOnVerticalChangedListener(
                    new NavigationBarView.OnVerticalChangedListener() {
                @Override
                public void onVerticalChanged(boolean isVertical) {
                    if (mAssistManager != null) {
                        mAssistManager.onConfigurationChanged();
                    }
                    mNotificationPanel.setQsScrimEnabled(!isVertical);
                }
            });
            mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    checkUserAutohide(v, event);
                    return false;
                }});
        }
    } catch (RemoteException ex) {
        // no window manager? good luck with that
    }

    mAssistManager = new AssistManager(this, context);

    // figure out which pixel-format to use for the status bar.
    mPixelFormat = PixelFormat.OPAQUE;

    mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
            R.id.notification_stack_scroller);
    mStackScroller.setLongPressListener(getNotificationLongClicker());
    mStackScroller.setPhoneStatusBar(this);
    mStackScroller.setGroupManager(mGroupManager);
    mStackScroller.setHeadsUpManager(mHeadsUpManager);
    mGroupManager.setOnGroupChangeListener(mStackScroller);

    mKeyguardIconOverflowContainer =
            (NotificationOverflowContainer) LayoutInflater.from(mContext).inflate(
                    R.layout.status_bar_notification_keyguard_overflow, mStackScroller, false);
    mKeyguardIconOverflowContainer.setOnActivatedListener(this);
    mKeyguardIconOverflowContainer.setOnClickListener(mOverflowClickListener);
    mStackScroller.setOverflowContainer(mKeyguardIconOverflowContainer);

    SpeedBumpView speedBump = (SpeedBumpView) LayoutInflater.from(mContext).inflate(
                    R.layout.status_bar_notification_speed_bump, mStackScroller, false);
    mStackScroller.setSpeedBumpView(speedBump);
    mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
            R.layout.status_bar_no_notifications, mStackScroller, false);
    mStackScroller.setEmptyShadeView(mEmptyShadeView);
    mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
            R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
    mDismissView.setOnButtonClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            MetricsLogger.action(mContext, MetricsLogger.ACTION_DISMISS_ALL_NOTES);
            clearAllNotifications();
        }
    });
    mStackScroller.setDismissView(mDismissView);
    mExpandedContents = mStackScroller;

    mBackdrop = (BackDropView) mStatusBarWindow.findViewById(R.id.backdrop);
    mBackdropFront = (ImageView) mBackdrop.findViewById(R.id.backdrop_front);
    mBackdropBack = (ImageView) mBackdrop.findViewById(R.id.backdrop_back);

    ScrimView scrimBehind = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_behind);
    ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
    View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim);
    mScrimController = new ScrimController(scrimBehind, scrimInFront, headsUpScrim,
            mScrimSrcModeEnabled);
    mHeadsUpManager.addListener(mScrimController);
    mStackScroller.setScrimController(mScrimController);
    mScrimController.setBackDropView(mBackdrop);
    mStatusBarView.setScrimController(mScrimController);
    mDozeScrimController = new DozeScrimController(mScrimController, context);

    mHeader = (StatusBarHeaderView) mStatusBarWindow.findViewById(R.id.header);
    mHeader.setActivityStarter(this);
    mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
    mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view);
    mKeyguardBottomArea =
            (KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
    mKeyguardBottomArea.setActivityStarter(this);
    mKeyguardBottomArea.setAssistManager(mAssistManager);
    mKeyguardIndicationController = new KeyguardIndicationController(mContext,
            (KeyguardIndicationTextView) mStatusBarWindow.findViewById(
                    R.id.keyguard_indication_text));
    mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);

    // set the inital view visibility
    setAreThereNotifications();

    mIconController = new StatusBarIconController(
            mContext, mStatusBarView, mKeyguardStatusBar, this);

    // Background thread for any controllers that need it.
    mHandlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
    mHandlerThread.start();

    // Other icons
    mLocationController = new LocationControllerImpl(mContext,
            mHandlerThread.getLooper()); // will post a notification
    mBatteryController = new BatteryController(mContext);
    mBatteryController.addStateChangedCallback(new BatteryStateChangeCallback() {
        @Override
        public void onPowerSaveChanged() {
            mHandler.post(mCheckBarModes);
            if (mDozeServiceHost != null) {
                mDozeServiceHost.firePowerSaveChanged(mBatteryController.isPowerSave());
            }
        }
        @Override
        public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
            // noop
        }
    });
    mNetworkController = new NetworkControllerImpl(mContext, mHandlerThread.getLooper());
    mHotspotController = new HotspotControllerImpl(mContext);
    mBluetoothController = new BluetoothControllerImpl(mContext, mHandlerThread.getLooper());
    mSecurityController = new SecurityControllerImpl(mContext);
    if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)) {
        mRotationLockController = new RotationLockControllerImpl(mContext);
    }
    mUserInfoController = new UserInfoController(mContext);
    mVolumeComponent = getComponent(VolumeComponent.class);
    if (mVolumeComponent != null) {
        mZenModeController = mVolumeComponent.getZenController();
    }
    mCastController = new CastControllerImpl(mContext);
    final SignalClusterView signalCluster =
            (SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster);
    final SignalClusterView signalClusterKeyguard =
            (SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster);
    final SignalClusterView signalClusterQs =
            (SignalClusterView) mHeader.findViewById(R.id.signal_cluster);
    mNetworkController.addSignalCallback(signalCluster);
    mNetworkController.addSignalCallback(signalClusterKeyguard);
    mNetworkController.addSignalCallback(signalClusterQs);
    signalCluster.setSecurityController(mSecurityController);
    signalCluster.setNetworkController(mNetworkController);
    signalClusterKeyguard.setSecurityController(mSecurityController);
    signalClusterKeyguard.setNetworkController(mNetworkController);
    signalClusterQs.setSecurityController(mSecurityController);
    signalClusterQs.setNetworkController(mNetworkController);
    final boolean isAPhone = mNetworkController.hasVoiceCallingFeature();
    if (isAPhone) {
        mNetworkController.addEmergencyListener(mHeader);
    }

    mFlashlightController = new FlashlightController(mContext);
    mKeyguardBottomArea.setFlashlightController(mFlashlightController);
    mKeyguardBottomArea.setPhoneStatusBar(this);
    mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
    mAccessibilityController = new AccessibilityController(mContext);
    mKeyguardBottomArea.setAccessibilityController(mAccessibilityController);
    mNextAlarmController = new NextAlarmController(mContext);
    mKeyguardMonitor = new KeyguardMonitor(mContext);
    if (UserSwitcherController.isUserSwitcherAvailable(UserManager.get(mContext))) {
        mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor,
                mHandler);
    }
    mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
            (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
            mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController);


    // Set up the quick settings tile panel
    mQSPanel = (QSPanel) mStatusBarWindow.findViewById(R.id.quick_settings_panel);
    if (mQSPanel != null) {
        final QSTileHost qsh = new QSTileHost(mContext, this,
                mBluetoothController, mLocationController, mRotationLockController,
                mNetworkController, mZenModeController, mHotspotController,
                mCastController, mFlashlightController,
                mUserSwitcherController, mKeyguardMonitor,
                mSecurityController);
        mQSPanel.setHost(qsh);
        mQSPanel.setTiles(qsh.getTiles());
        mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow);
        mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
        mHeader.setQSPanel(mQSPanel);
        qsh.setCallback(new QSTileHost.Callback() {
            @Override
            public void onTilesChanged() {
                mQSPanel.setTiles(qsh.getTiles());
            }
        });
    }

    // User info. Trigger first load.
    mHeader.setUserInfoController(mUserInfoController);
    mKeyguardStatusBar.setUserInfoController(mUserInfoController);
    mKeyguardStatusBar.setUserSwitcherController(mUserSwitcherController);
    mUserInfoController.reloadUserInfo();

    mHeader.setBatteryController(mBatteryController);
    ((BatteryMeterView) mStatusBarView.findViewById(R.id.battery)).setBatteryController(
            mBatteryController);
    mKeyguardStatusBar.setBatteryController(mBatteryController);
    mHeader.setNextAlarmController(mNextAlarmController);

    PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
    mBroadcastReceiver.onReceive(mContext,
            new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF));


    // receive broadcasts
    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
    filter.addAction(Intent.ACTION_SCREEN_OFF);
    filter.addAction(Intent.ACTION_SCREEN_ON);
    context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);

    IntentFilter demoFilter = new IntentFilter();
    if (DEBUG_MEDIA_FAKE_ARTWORK) {
        demoFilter.addAction(ACTION_FAKE_ARTWORK);
    }
    demoFilter.addAction(ACTION_DEMO);
    context.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter,
            android.Manifest.permission.DUMP, null);

    // listen for USER_SETUP_COMPLETE setting (per-user)
    resetUserSetupObserver();

    // disable profiling bars, since they overlap and clutter the output on app windows
    ThreadedRenderer.overrideProperty("disableProfileBars", "true");

    // Private API call to make the shadows look better for Recents
    ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));

    return mStatusBarView;
}
![狀態(tài)欄控件樹(shù)的結(jié)構(gòu)](http://upload-images.jianshu.io/upload_images/2043394-ddde815f8966729f?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蒋畜,隨后出現(xiàn)的幾起案子声畏,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件插龄,死亡現(xiàn)場(chǎng)離奇詭異愿棋,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)均牢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)糠雨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人徘跪,你說(shuō)我怎么就攤上這事甘邀。” “怎么了垮庐?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵松邪,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我突硝,道長(zhǎng)测摔,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任解恰,我火速辦了婚禮锋八,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘护盈。我一直安慰自己挟纱,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布腐宋。 她就那樣靜靜地躺著紊服,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胸竞。 梳的紋絲不亂的頭發(fā)上欺嗤,一...
    開(kāi)封第一講書(shū)人閱讀 51,573評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音卫枝,去河邊找鬼煎饼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛校赤,可吹牛的內(nèi)容都是我干的吆玖。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼马篮,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼沾乘!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起浑测,我...
    開(kāi)封第一講書(shū)人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤翅阵,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體掷匠,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡读慎,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了槐雾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡幅狮,死狀恐怖募强,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情崇摄,我是刑警寧澤擎值,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站逐抑,受9級(jí)特大地震影響鸠儿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜厕氨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一进每、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧命斧,春花似錦田晚、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至汇四,卻和暖如春接奈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背通孽。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工序宦, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人利虫。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓挨厚,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親糠惫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子疫剃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容