概述
下面两图让我们大概的了解了SystemUI代码结构和布局范围。
下面是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启动流程图
高清大图请看 百度云 链接:https://pan.baidu.com/s/1NIJn2m3521v9fGys_9rDwQ 密码:bws9
最后
以上就是愤怒水杯为你收集整理的phonestatusbar.java_SystemUI源码分析之PhoneStatusBar启动流程简单分析的全部内容,希望文章能够帮你解决phonestatusbar.java_SystemUI源码分析之PhoneStatusBar启动流程简单分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复