建设能播放视频的网站,东莞建设网住房保障专栏20批公示栏,古装衣服店网站建设页面,莱芜在线论坛视频首语
SystemUI(System User Interface)是Android 系统为用户提供的系统级别的信息显示与交互的UI组件应用程序#xff0c;包含状态栏、导航栏、锁屏、通知面板、快速设置、最近任务等#xff0c;它们各部分独立#xff0c;各尽其责。
SystemUI是一个常驻应用程序#xff…首语
SystemUI(System User Interface)是Android 系统为用户提供的系统级别的信息显示与交互的UI组件应用程序包含状态栏、导航栏、锁屏、通知面板、快速设置、最近任务等它们各部分独立各尽其责。
SystemUI是一个常驻应用程序只要系统运行它就会一直运行即使被杀死也会重新启动。
源码目录
SystemUI源码目录在frameworks/base/package下和Settings不一样它不在package/apps下。
从Android.bp文件中可以得出模块名为SystemUI。
架构
SystemUI各组件经常会互相交互例如点击通知面板通知在锁屏情况下会跳转锁屏页面先解锁解锁情况下跳转锁屏内容页面因此通知面板需要清楚锁屏状态来进行处理。为此需要设计好架构还轻松获取到各个组件避免产生很多的创建代码SystemUI使用了依赖注入自动创建对象SystemUI使用Dagger2来作为依赖注入库管理组件。
Android系统中为了适应多元化场景诸如TV、Car它们又是不同的UI组件同时满足模块化设计因此将SytemUI独立成一个单独的、常驻内存的应用程序。
SystemUI各种组件UI均存在UIController来进行UI逻辑的处理和交互不同组件源码通过目录清晰划分。
关于Dagger2可参考以下文档 Android 官方https://developer.android.google.cn/training/dependency-injection/dagger-basics?hlzh_cn Dagger: https://dagger.dev/dev-guide
AndroidManifest
由Manifest可以看出SystemUI是一个比较特殊的应用程序有许多特定设置项。
manifest xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:androidprvhttp://schemas.android.com/apk/prv/res/androidpackagecom.android.systemui!--指定共享的uid--android:sharedUserIdandroid.uid.systemuixmlns:toolshttp://schemas.android.com/toolscoreApptrueapplicationandroid:name.SystemUIApplicationandroid:persistenttrue!--不允许清除应用数据--android:allowClearUserDatafalseandroid:backupAgent.backup.BackupHelper!--应用程序被恢复后继续运行--android:killAfterRestorefalse!--启用硬件加速--android:hardwareAcceleratedtrueandroid:labelstring/app_labelandroid:icondrawable/icon!--指定进程--android:processcom.android.systemuiandroid:supportsRtltrueandroid:themestyle/Theme.SystemUI!--默认存储空间重定向到data/user_de--android:defaultToDeviceProtectedStoragetrue!--DirectBoot 模式下可以启动--android:directBootAwaretruetools:replaceandroid:appComponentFactory!--指定应用程序组件工厂,动态创建和初始化组件--android:appComponentFactory.SystemUIAppComponentFactory/application
/manifest启动流程
在SystemServer 进程启动过程文章中我们清楚SystemServer进程主要工作是启动系统服务其中在startOtherServices方法中当AMS系统服务进入就绪状态时会调用startSystemUi方法来启动SystemUI其中AMS是在startBootstrapServices方法中被启动的。在startSystemUi方法中启动了一个服务服务intent的component通过PackageManagerInternal类的getSystemUiServiceComponent方法获取PackageManagerInternal是一个抽象类它的实现在PackageManagerInternalBase类中可以看到getSystemUiServiceComponent实现中返回了config_systemUIServiceComponent字符串。
源码路径frameworks\base\services\java\com\android\server\SystemServer.java
private void startOtherServices(NonNull TimingsTraceAndSlog t) {...mActivityManagerService.systemReady(() - {...t.traceBegin(StartSystemUI);try {startSystemUi(context, windowManagerF);} catch (Throwable e) {reportWtf(starting System UI, e);}t.traceEnd();},t);
}
private static void startSystemUi(Context context, WindowManagerService windowManager) {PackageManagerInternal pm LocalServices.getService(PackageManagerInternal.class);Intent intent new Intent();intent.setComponent(pm.getSystemUiServiceComponent());intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);//Slog.d(TAG, Starting service: intent);context.startServiceAsUser(intent, UserHandle.SYSTEM);windowManager.onSystemUiStarted();}源码路径frameworks\base\services\core\java\com\android\server\pm\PackageManagerInternalBase.java
Override
Deprecated
public final ComponentName getSystemUiServiceComponent() {return ComponentName.unflattenFromString(getContext().getResources().getString(com.android.internal.R.string.config_systemUIServiceComponent));
}可以看到指定的Component包名为com.android.systemui类名为com.android.systemui.SystemUIService。
到这里我们就清楚SystemUI是SystemServer进程启动SystemUIService来启动的。
源码路径frameworks\base\core\res\res\values\config.xml
!-- SystemUi service component --
string nameconfig_systemUIServiceComponent translatablefalsecom.android.systemui/com.android.systemui.SystemUIService/stringSystemUIService类中调用SystemUIApplication类的startServicesIfNeeded方法。
源码路径frameworks\base\packages\SystemUI\src\com\android\systemui\SystemUIService.java
Override
public void onCreate() {super.onCreate();// Start all of SystemUI((SystemUIApplication) getApplication()).startServicesIfNeeded();...}首先获取定制的系统UI组件其为VenderService。继续通过getStartableComponents和getStartableComponentsPerUser方法获取组件
源码路径frameworks\base\packages\SystemUI\src\com\android\systemui\SystemUIApplication.java
public void startServicesIfNeeded() {//定制系统UI组件final String vendorComponent SystemUIFactory.getInstance().getVendorComponent(getResources());MapClass?, ProviderCoreStartable sortedStartables new TreeMap(Comparator.comparing(Class::getName));sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponents());sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponentsPerUser());startServicesIfNeeded(sortedStartables, StartServices, vendorComponent);
}源码路径frameworks\base\packages\SystemUI\src\com\android\systemui\SystemUIFactory.java
// string nameconfig_systemUIVendorServiceComponent translatablefalsecom.android.systemui.VendorServices/string
public String getVendorComponent(Resources resources) {return resources.getString(R.string.config_systemUIVendorServiceComponent);
}
public MapClass?, ProviderCoreStartable getStartableComponents() {return mSysUIComponent.getStartables();
}
public MapClass?, ProviderCoreStartable getStartableComponentsPerUser() {return mSysUIComponent.getPerUserStartables();
}这里使用了Dagger2的IntoMap注入相关类只要是继承CoreStartable类的都将会被注入。
源码路径frameworks\base\packages\SystemUI\src\com\android\systemui\dagger\SysUIComponent.java
SysUISingleton
Subcomponent(modules {DefaultComponentBinder.class,DependencyProvider.class,SystemUIBinder.class,SystemUIModule.class,SystemUICoreStartableModule.class,ReferenceSystemUIModule.class})
public interface SysUIComponent {MapClass?, ProviderCoreStartable getStartables();PerUser MapClass?, ProviderCoreStartable getPerUserStartables();
}
注入方法如下相关注入结束后继续回到SystemUIApplication类的startServicesIfNeeded方法。
源码路径frameworks\base\packages\SystemUI\src\com\android\systemui\dagger\SystemUICoreStartableModule.kt
Module
abstract class SystemUICoreStartableModule {/** Inject into AuthController. */BindsIntoMapClassKey(AuthController::class)abstract fun bindAuthController(service: AuthController): CoreStartable/** Inject into ClipboardListener. */BindsIntoMapClassKey(ClipboardListener::class)abstract fun bindClipboardListener(sysui: ClipboardListener): CoreStartable......
}获取所有组件后启动所有组件至此System UI和SystemUI所有组件启动完成。
private void startServicesIfNeeded(MapClass?, ProviderCoreStartable startables,String metricsPrefix,String vendorComponent) {if (mServicesStarted) {return;}mServices new CoreStartable[startables.size() (vendorComponent null ? 0 : 1)];if (!mBootCompleteCache.isBootComplete()) {// check to see if maybe it was already completed long before we began// see ActivityManagerService.finishBooting()if (1.equals(SystemProperties.get(sys.boot_completed))) {mBootCompleteCache.setBootComplete();if (DEBUG) {Log.v(TAG, BOOT_COMPLETED was already sent);}}}mDumpManager mSysUIComponent.createDumpManager();Log.v(TAG, Starting SystemUI services for user Process.myUserHandle().getIdentifier() .);TimingsTraceLog log new TimingsTraceLog(SystemUIBootTiming,Trace.TRACE_TAG_APP);log.traceBegin(metricsPrefix);int i 0;for (Map.EntryClass?, ProviderCoreStartable entry : startables.entrySet()) {String clsName entry.getKey().getName();int j i; // Copied to make lambda happy.timeInitialization(clsName,//启动组件() - mServices[j] startStartable(clsName, entry.getValue()),log,metricsPrefix);i;}if (vendorComponent ! null) {timeInitialization(vendorComponent,() - mServices[mServices.length - 1] startAdditionalStartable(vendorComponent),log,metricsPrefix);}for (i 0; i mServices.length; i) {if (mBootCompleteCache.isBootComplete()) {mServices[i].onBootCompleted();}mDumpManager.registerDumpable(mServices[i].getClass().getName(), mServices[i]);}mSysUIComponent.getInitController().executePostInitTasks();log.traceEnd();mServicesStarted true;}
private CoreStartable startStartable(String clsName, ProviderCoreStartable provider) {if (DEBUG) Log.d(TAG, loading: clsName);return startStartable(provider.get());}private CoreStartable startStartable(CoreStartable startable) {if (DEBUG) Log.d(TAG, running: startable);startable.start();return startable;}总结
SystemUI是Android系统中与用户交互频繁的UI组件应用程序地位不言而喻。后续会对SystemUI中重要的组件进行单独分析深入了解。同时对于这个一个UI组件应用程序Android 14引入了Jetpack Compse进行部分UI代码的重构在保持稳定性的前提下官方会持续进行重构到时架构及实现将会发生重大变化。
官方文档frameworks/base/package/SystemUI/docs/