我是靠谱客的博主 愤怒水杯,最近开发中收集的这篇文章主要介绍phonestatusbar.java_SystemUI源码分析之PhoneStatusBar启动流程简单分析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

af975254a808d8098617c7bcc811dd78.png

下面两图让我们大概的了解了SystemUI代码结构和布局范围。

43fdb8e12ed586d79a89f0649b670ec9.png

dfb424dac587bde79e2528ab39a6bb4c.png

下面是Android SystemUI中包含的各项功能简介,虽然很多,但我这里只是讲解Status Bar,也就是系统上方的状态栏。看第二张图第一部分的顶部部分。

Status Bar 系统上方的状态栏

Navigator Bar 系统下方的导航栏

Keyguard 锁屏界面

PowerUI 电源界面

Recents Screen 近期任务界面

VolumeUI 音量调节对话框

Stack Divider 分屏功能调节器

PipUI 画中画界面

Screenshot 截屏界面

RingtonePlayer 铃声播放器界面

Settings Activity 系统设置中用到的一些界面,例如:NetworkOverLimitActivity,UsbDebuggingActivity等。

原归正传,我们从代码中查看SystemUI是如何启动的。我用的源码是Android 6.0 的,不过各个Android版本的启动过程大致是相同的。

1.SystemServer中启动SystemUIService

SystemService路径: baseservicesjavacomandroidserverSystemServer.java

SystemUIService的启动是在SystemServer中startSystemUi中启动的

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);

}

而startSystemUi()在SystemServer中启动startOtherServices()中调用的。

private void startOtherServices() {

......

mActivityManagerService.systemReady(new Runnable() {

@Override

public void run() {

.......

try {

startSystemUi(context);

} catch (Throwable e) {

reportWtf("starting System UI", e);

}

......

}

}

......

}

2. SystemUIService服务的启动

SystemUIService所在路径: srccomandroidsystemuiSystemUIService.java

SystemUIApplication所在路径: srccomandroidsystemuiSystemUIApplication.java

根据上面设置的包名,我们知道SystemUIService是在/frameworks/base/packages/SystemUI中,也就是SystemUI系统应用。

在Android中,我们第一次启动应用会先启动application模块(如果在AndroidMainfest.xml有配置的话),然后才会启动application中包含的Activity、Service、广播等组件。

因此我们先看SystemUI中的application模块也就是SystemUIApplication.java(具体看AndroidMainfest.xml中的配置)代码:

public class SystemUIApplication extends Application {

......

/**

* 假“服务”,这些“服务”都继承抽象了SystemUI,也不是真正的“服务”

*/

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,

};

......

@Override

public void onCreate() {

super.onCreate();

setTheme(R.style.systemui_theme);

//注册开机完成广播监听

IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);

filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);

registerReceiver(new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

if (mBootCompleted) return;

if (DEBUG) Log.v(TAG, "BOOT_COMPLETED received");

unregisterReceiver(this);

mBootCompleted = true;

if (mServicesStarted) {

final int N = mServices.length;

for (int i = 0; i < N; i++) {

mServices[i].onBootCompleted();

}

}

}

}, filter);

}

// 启动上面那些“服务”,在SystemUIService中被调用

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

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(); //调用start()方法

if (mBootCompleted) {

mServices[i].onBootCompleted();//调用onBootCompleted方法

}

}

mServicesStarted = true;

}

//横竖改变了,需要通知对应的“Service”进行相对应的配置

@Override

public void onConfigurationChanged(Configuration newConfig) {

if (mServicesStarted) {

int len = mServices.length;

for (int i = 0; i < len; i++) {

mServices[i].onConfigurationChanged(newConfig);

}

}

}

......

}

启动完SystemUIApplication后,才启动SystemUIService.java

public class SystemUIService extends Service {

@Override

public void onCreate() {

super.onCreate();

((SystemUIApplication) getApplication()).startServicesIfNeeded(); //这里SystemUIApplication中的startServicesIfNeeded,启动“服务”

}

......

}

在上面中,启动了的“服务”有TunerService、KeyguardViewMediator、Recents、VolumeUI、SystemBars等,但我们这次只讲解SystemBars“服务”的启动。

在startServicesIfNeeded()中,我们知道先初始化服“服务”,然后调用“服务”的start()方法

3. SystemBars“服务”的启动

启动的就是SystemBars.java

所在路径: srccomandroidsystemuistatusbarSystemBars.java

重点看start()方法

public class SystemBars extends SystemUI implements ServiceMonitor.Callbacks {

......

//start()方法是再启动中调用的额方法

@Override

public void start() {

if (DEBUG) Log.d(TAG, "start");

//这里会启动ServiceMonitor,并调用其的start(),重点看注释“如果没有远程服务,就会回调onNoService()方法”

mServiceMonitor = new ServiceMonitor(TAG, DEBUG,

mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);

mServiceMonitor.start(); // will call onNoService if no remote service is found

}

@Override

public void onNoService() {

if (DEBUG) Log.d(TAG, "onNoService");

createStatusBarFromConfig(); // fallback to using an in-process implementation

}

......

}

第一次启动时,远程服务没有被启动,因此会回调onNoService()方法,然后调用createStatusBarFromConfig()方法,继续

private void createStatusBarFromConfig() {

if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");

//根据xml中的配置,是一个应用包名路径,这里就是“com.android.systemui.statusbar.phone.PhoneStatusBar”

//然后根据包名路径并启动

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;

//这里调用mStausBar就是“PhoneStatusBar”实例,并调用start()方法

mStatusBar.start();

if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());

}

R.string.config_statusBarComponent配置的是“com.android.systemui.statusbar.phone.PhoneStatusBar”

然后就会启动PhoneStatusBar.java,重点,这里在启动后又调用了start()方法。

4. PhoneStatusBar.start()

public class PhoneStatusBar extends BaseStatusBar implements DemoMode,

DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,

HeadsUpManager.OnHeadsUpChangedListener {

......

@Override

public void start() {

......

super.start(); // calls createAndAddWindows()

......

addNavigationBar();

// Lastly, call to the icon policy to install/update all the icons.

mIconPolicy = new PhoneStatusBarPolicy(mContext, mCastController, mHotspotController,

mUserInfoController, mBluetoothController);

mIconPolicy.setCurrentUserSetup(mUserSetup);

......

startKeyguard();

......

}

......

}

在 PhoneStatusBar.start()中重点如下几个步骤:

1.createAndAddWindows() 初始化View,顶部状态栏,和底部导航栏

2.addNavigationBar()

3.PhoneStatusBarPolicy() 用于初始化以及更新StatusBar上的icons

4.startKeyguard() 启动屏锁

具体的后续在分析。

5.PhoneStatusBar启动流程图

07b372289d3f1b70f9c53d696a0b22fa.png

高清大图请看   百度云 链接:https://pan.baidu.com/s/1NIJn2m3521v9fGys_9rDwQ 密码:bws9

最后

以上就是愤怒水杯为你收集整理的phonestatusbar.java_SystemUI源码分析之PhoneStatusBar启动流程简单分析的全部内容,希望文章能够帮你解决phonestatusbar.java_SystemUI源码分析之PhoneStatusBar启动流程简单分析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部