欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

目錄

車(chē)載系統(tǒng) Android 車(chē)載應(yīng)用開(kāi)發(fā)指南(3) - SystemUI 詳解

Android 車(chē)載應(yīng)用開(kāi)發(fā)指南系列文章

Android 車(chē)載應(yīng)用開(kāi)發(fā)指南(1)- 車(chē)載操作系統(tǒng)全解析

Android 車(chē)載應(yīng)用開(kāi)發(fā)指南(2)- 應(yīng)用開(kāi)發(fā)入門(mén)

Android 車(chē)載應(yīng)用開(kāi)發(fā)指南(3)- SystemUI 詳解

一 SystemUI 概述

SystemUI全稱(chēng)System User Interface,直譯過(guò)來(lái)就是系統(tǒng)級(jí)用戶(hù)交互界面,在 Android 系統(tǒng)中由SystemUI負(fù)責(zé)統(tǒng)一管理整個(gè)系統(tǒng)層的 UI,它是一個(gè)系統(tǒng)級(jí)應(yīng)用程序(APK),源碼在/frameworks/base/packages/目錄下。

1.1 SystemUI

Android - Phone中SystemUI從源碼量看就是一個(gè)相當(dāng)復(fù)雜的程序,常見(jiàn)的如:狀態(tài)欄、消息中心、近期任務(wù)、截屏以及一系列功能都是在SystemUI中實(shí)現(xiàn)的。

源碼位置:/frameworks/base/packages/SystemUI

常見(jiàn) UI 組件有(包含但不限于,完整列表可以查看 SystemUI 服務(wù)組件列表)

狀態(tài)欄 StatusBar導(dǎo)航欄 NavigationBar通知欄 NotificationPanel快捷按鍵欄 QSPanel最近任務(wù) Recent鍵盤(pán)鎖 Keyguard

原生 Android 系統(tǒng)中 SystemUI 大概是這樣

1.2 CarSystemUI

Android-AutoMotive中的SystemUI相對(duì)手機(jī)中要簡(jiǎn)單不少,目前商用車(chē)載系統(tǒng)中幾乎必備的頂部狀態(tài)欄、消息中心、底部導(dǎo)航欄在原生的Android系統(tǒng)中都已經(jīng)實(shí)現(xiàn)了。

源碼位置:frameworks/base/packages/CarSystemUI

雖然CarSystemUI與SystemUI的源碼位置不同,但是二者實(shí)際上是復(fù)用關(guān)系。通過(guò)閱讀CarSystemUI的 Android.bp 文件可以發(fā)現(xiàn)CarSystemUI在編譯時(shí)把SystemUI以靜態(tài)庫(kù)的方式引入進(jìn)來(lái)了。

android.bp 源碼位置:/frameworks/base/packages/CarSystemUI/Android.bp

android_library {

name: "CarSystemUI-core",

...

static_libs: [

"SystemUI-core",

"SystemUIPluginLib",

"SystemUISharedLib",

"SystemUI-tags",

"SystemUI-proto",

...

],

...

}

二 SystemUI 啟動(dòng)流程

System UI的啟動(dòng)大致可分為以下兩個(gè)流程:

在Framework中啟動(dòng)SystemUIService在SystemUIService中啟動(dòng)SystemUI所需的各種組件

說(shuō)明:本文源碼分析基于版本:android-12.0.0_r3

2.1 Framework 中的流程

SystemUI 是系統(tǒng)應(yīng)用,所以它也是一個(gè) APK,有入口 Application,只不過(guò)它是由 system_server 進(jìn)程直接啟動(dòng)的。

關(guān)于SystemServer,它是 Android framework 中關(guān)鍵系統(tǒng)的服務(wù),由 Android 系統(tǒng)最核心的進(jìn)程Zygotefork 生成,進(jìn)程名為system_server。常見(jiàn)的ActivityManagerService、PackageManagerService、WindowManageService都是由SystemServer啟動(dòng)的。

SystemServer 源碼路徑:/frameworks/base/services/java/com/android/server/SystemServer.java

第一步:SystemServer 的 main() 方法中調(diào)用 SystemServer.run(),run()中調(diào)用startOtherServices()

public static void main(String[] args) {

new SystemServer().run();

}

private void run() {

... ...

// Start services.

try {

startBootstrapServices(t);

startCoreServices(t);

startOtherServices(t); //SystemServer在startOtherServices()被啟動(dòng)

}

... ...

}

第二步:startOtherServices()中通過(guò)AMS的回調(diào)方法ready(),然后調(diào)用startSystemUi()

mActivityManagerService.systemReady(() -> {

... ...

try {

startSystemUi(context, windowManagerF);

} catch (Throwable e) {

reportWtf("starting System UI", e);

}

... ...

,t);

第三步:startSystemUi()中可以看出,SystemUI本質(zhì)就是一個(gè)Service,通過(guò)PM獲取到的Component 是com.android.systemui/.SystemUIService,然后通過(guò)調(diào)用context.startServiceAsUser()完成對(duì)SystemUIService的啟動(dòng)。

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

}

第四步:SystemUIService 依附于SystemUI應(yīng)用,所以SystemUIService啟動(dòng)前需要完成SystemUI整個(gè)應(yīng)用的啟動(dòng),其流程也就是應(yīng)用常見(jiàn)的冷啟動(dòng)流程,這里展開(kāi)講一下:

SystemUI 應(yīng)用啟動(dòng)流程 context中的startServiceAsUser()是一個(gè)抽象方法,具體實(shí)現(xiàn)在ContextImpl.java里。實(shí)現(xiàn)方法startServiceCommon()中,通過(guò)ActivityManager.getService()就會(huì)走到AMS中,最終在AMS來(lái)啟動(dòng)SystemUIService。

@Override

public ComponentName startServiceAsUser(Intent service, UserHandle user) {

return startServiceCommon(service, false, user);

}

@Override

private ComponentName startServiceCommon(Intent service, boolean requireForeground,

UserHandle user) {

try {

validateServiceIntent(service);

service.prepareToLeaveProcess(this);

ComponentName cn = ActivityManager.getService().startService( //在AMS中開(kāi)啟Service

mMainThread.getApplicationThread(), service,

service.resolveTypeIfNeeded(getContentResolver()), requireForeground,

getOpPackageName(), getAttributionTag(), user.getIdentifier());

... ...

} catch (RemoteException e) {

throw e.rethrowFromSystemServer();

}

}

接下來(lái)進(jìn)入AMS,一探究竟:

AMS 源碼路徑:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

在AMS的startService()方法里,會(huì)經(jīng)過(guò)一系列內(nèi)部流程,調(diào)用到bringUpServiceLocked()方法。

@Override

public ComponentName startService(IApplicationThread caller, Intent service,

String resolvedType, boolean requireForeground, String callingPackage,

String callingFeatureId, int userId)

throws TransactionTooLargeException {

... ...

try {

res = mServices.startServiceLocked(caller, service,

resolvedType, callingPid, callingUid,

requireForeground, callingPackage, callingFeatureId, userId); // 內(nèi)部調(diào)用到 startServiceLocked()

}

... ...

}

}

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, boolean fgRequired, String callingPackage,

@Nullable String callingFeatureId, final int userId,

boolean allowBackgroundActivityStarts) throws TransactionTooLargeException {

... ...

if (caller != null) {

// 這里記錄app的進(jìn)程信息

final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);

... ...

ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting); //內(nèi)部調(diào)用到startServiceInnerLocked()

... ...

return cmp;

}

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {

... ...

String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false); //調(diào)用到bringUpServiceLocked()

if (error != null) {

return new ComponentName("!!", error);

}

... ...

return r.name;

}

繼續(xù)調(diào)用了bringUpServiceLocked()方法,

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting, boolean permissionsReviewRequired)

throws TransactionTooLargeException {

... ...

if (!isolated) {

app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);

if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app);

//如果service進(jìn)程存在

if (app != null && app.thread != null) {

try {

app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);

//啟動(dòng)service

realStartServiceLocked(r, app, execInFg);

return null;

} catch (TransactionTooLargeException e) {

throw e;

} catch (RemoteException e) {

Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e);

}

}

}

... ...

// 如果不存在此進(jìn)程

if (app == null && !permissionsReviewRequired) {

// 啟動(dòng)運(yùn)行的線程

if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,

hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated, false)) == null) {

String msg = "Unable to launch app "

+ r.appInfo.packageName + "/"

+ r.appInfo.uid + " for service "

+ r.intent.getIntent() + ": process is bad";

Slog.w(TAG, msg);

bringDownServiceLocked(r);

return msg;

}

}

... ...

return null;

}

這個(gè)方法做了兩件事:

如果SystemUIService所屬進(jìn)程已經(jīng)存在,則直接調(diào)用realStartServiceLocked()。如果SystemUIService所屬進(jìn)程不存在,則執(zhí)行startProcessLocked()方法創(chuàng)建進(jìn)程,經(jīng)過(guò)層層調(diào)用,最終也會(huì)走到realStartServiceLocked()中:

private final void realStartServiceLocked(ServiceRecord r,

ProcessRecord app, boolean execInFg) throws RemoteException {

... ...

try {

... ...

app.thread.scheduleCreateService(r, r.serviceInfo,

mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),

app.getReportedProcState());

r.postNotification();

created = true;

}

}

這個(gè)方法內(nèi)部調(diào)用了app.thread.scheduleCreateService(),而app.thread是一個(gè)IApplicationThread類(lèi)型的,他的實(shí)現(xiàn)是ActivityThread的一個(gè)內(nèi)部類(lèi)ApplicationThread,而這個(gè)類(lèi)正好實(shí)現(xiàn)了IApplicationThread.Stub,在ApplicationThread類(lèi)中,找到對(duì)應(yīng)的調(diào)用方法:

public final void scheduleCreateService(IBinder token,

ServiceInfo info, CompatibilityInfo compatInfo, int processState) {

updateProcessState(processState, false);

CreateServiceData s = new CreateServiceData();

s.token = token;

s.info = info;

s.compatInfo = compatInfo;

sendMessage(H.CREATE_SERVICE, s);

}

可以看出,是發(fā)送一個(gè)消息給Handler,這個(gè)Handler是ActivityThread的內(nèi)部類(lèi)H

public void handleMessage(Message msg) {

switch (msg.what) {

... ...

case CREATE_SERVICE:

if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,

("serviceCreate: " + String.valueOf(msg.obj)));

}

handleCreateService((CreateServiceData)msg.obj);

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

break;

... ...

}

}

最終調(diào)用了handleCreateService()方法:

private void handleCreateService(CreateServiceData data) {

LoadedApk packageInfo = getPackageInfoNoCheck(

data.info.applicationInfo, data.compatInfo);

Service service = null;

try {

//創(chuàng)建service的context

ContextImpl context = ContextImpl.createAppContext(this, packageInfo);

//創(chuàng)建Application

Application app = packageInfo.makeApplication(false, mInstrumentation);

//獲取類(lèi)加載器

java.lang.ClassLoader cl = packageInfo.getClassLoader();

//加載service實(shí)例

service = packageInfo.getAppFactory()

.instantiateService(cl, data.info.name, data.intent);

// Service resources must be initialized with the same loaders as the application

// context.

context.getResources().addLoaders(

app.getResources().getLoaders().toArray(new ResourcesLoader[0]));

context.setOuterContext(service);

//初始化service

service.attach(context, this, data.info.name, data.token, app,

ActivityManager.getService());

//調(diào)用service的onCreate方法

service.onCreate();

mServices.put(data.token, service);

try {

//通過(guò)serviceDoneExecuting告知AMS,service已經(jīng)啟動(dòng)完成

ActivityManager.getService().serviceDoneExecuting(

data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);

} catch (RemoteException e) {

throw e.rethrowFromSystemServer();

}

} catch (Exception e) {

if (!mInstrumentation.onException(service, e)) {

throw new RuntimeException(

"Unable to create service " + data.info.name

+ ": " + e.toString(), e);

}

}

}

這個(gè)方法主要做了以下幾件事:

首先,創(chuàng)建上下文創(chuàng)建SystemUIApplication,獲取類(lèi)加載器加載SystemUIService實(shí)例,初始化SystemUIService, 調(diào)用onCreate()方法最后通知AMS,SystemUIService啟動(dòng)完成。

到這里SystemUIService已經(jīng)啟動(dòng)完成。

第五步: 前面在SystemUIApplication創(chuàng)建成功后會(huì)回調(diào)內(nèi)部的OnCreate()方法,在OnCreate()中方法注冊(cè)了一個(gè)開(kāi)機(jī)廣播,當(dāng)接收到開(kāi)機(jī)廣播后會(huì)調(diào)用SystemUI的onBootCompleted()方法來(lái)告訴每個(gè)子模塊 Android 系統(tǒng)已經(jīng)完成開(kāi)機(jī)。

@Override

public void onCreate() {

super.onCreate();

Log.v(TAG, "SystemUIApplication created.");

// 設(shè)置所有服務(wù)繼承的應(yīng)用程序主題。

// 請(qǐng)注意,在清單中設(shè)置應(yīng)用程序主題僅適用于activity。這里是讓Service保持與主題設(shè)置同步。

setTheme(R.style.Theme_SystemUI);

if (Process.myUserHandle().equals(UserHandle.SYSTEM)) {

IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);

bootCompletedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);

registerReceiver(new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

if (mBootCompleteCache.isBootComplete()) return;

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

unregisterReceiver(this);

mBootCompleteCache.setBootComplete();

if (mServicesStarted) {

final int N = mServices.length;

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

mServices[i].onBootCompleted(); //通知SystemUI子模塊

}

}

}

}, bootCompletedFilter);

...

} else {

// 我們不需要為正在執(zhí)行某些任務(wù)的子進(jìn)程啟動(dòng)服務(wù)。

...

}

}

2.2 SystemUI 中的流程

第六步:SystemUIService初始化完成后會(huì)調(diào)用onCreate()方法,onCreate()中調(diào)用了SystemUIApplication中的startServiceIfNeeded()方法完成SystemUI子模塊的初始化。

SystemUIService 源碼位置:/frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java

public class SystemUIService extends Service {

... ...

@Override

public void onCreate() {

super.onCreate();

// Start all of SystemUI

((SystemUIApplication) getApplication()).startServicesIfNeeded(); //調(diào)用startServicesIfNeeded()

... ...

}

}

第七步: 在SystemUIApplication的startServicesIfNeeded()方法中,通過(guò)SystemUIFactory獲取到配置在config.xml中每個(gè)子模塊的className。

SystemUIApplication 源碼位置:/frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java

// SystemUIApplication

public void startServicesIfNeeded() {

String[] names = SystemUIFactory.getInstance().getSystemUIServiceComponents(getResources());

startServicesIfNeeded("StartServices", names);

}

// SystemUIFactory

/** Returns the list of system UI components that should be started. */

public String[] getSystemUIServiceComponents(Resources resources) {

return resources.getStringArray(R.array.config_systemUIServiceComponents);

}

config.xml 位置:/frameworks/base/packages/SystemUI/res/values/config.xml

com.android.systemui.util.NotificationChannels

com.android.systemui.keyguard.KeyguardViewMediator

com.android.systemui.recents.Recents

com.android.systemui.volume.VolumeUI

com.android.systemui.stackdivider.Divider

com.android.systemui.statusbar.phone.StatusBar

com.android.systemui.usb.StorageNotification

com.android.systemui.power.PowerUI

com.android.systemui.media.RingtonePlayer

com.android.systemui.keyboard.KeyboardUI

com.android.systemui.pip.PipUI

com.android.systemui.shortcut.ShortcutKeyDispatcher

@string/config_systemUIVendorServiceComponent

com.android.systemui.util.leak.GarbageMonitor$Service

com.android.systemui.LatencyTester

com.android.systemui.globalactions.GlobalActionsComponent

com.android.systemui.ScreenDecorations

com.android.systemui.biometrics.AuthController

com.android.systemui.SliceBroadcastRelayHandler

com.android.systemui.SizeCompatModeActivityController

com.android.systemui.statusbar.notification.InstantAppNotifier

com.android.systemui.theme.ThemeOverlayController

com.android.systemui.accessibility.WindowMagnification

com.android.systemui.accessibility.SystemActions

com.android.systemui.toast.ToastUI

第八步: 在startServicesIfNeeded()中通過(guò)反射完成了每個(gè)SystemUI組件的創(chuàng)建,然后再調(diào)用各個(gè)SystemUI的onStart()方法來(lái)繼續(xù)執(zhí)行子模塊的初始化。

private SystemUI[] mServices;

private void startServicesIfNeeded(String metricsPrefix, String[] services) {

if (mServicesStarted) {

return;

}

mServices = new SystemUI[services.length];

...

final int N = services.length;

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

String clsName = services[i];

if (DEBUG) Log.d(TAG, "loading: " + clsName);

try {

SystemUI obj = mComponentHelper.resolveSystemUI(clsName);

if (obj == null) {

Constructor constructor = Class.forName(clsName).getConstructor(Context.class);

obj = (SystemUI) constructor.newInstance(this);

}

mServices[i] = obj;

} catch (ClassNotFoundException

| NoSuchMethodException

| IllegalAccessException

| InstantiationException

| InvocationTargetException ex) {

throw new RuntimeException(ex);

}

if (DEBUG) Log.d(TAG, "running: " + mServices[i]);

// 調(diào)用各個(gè)子模塊的start()

mServices[i].start();

// 首次啟動(dòng)時(shí),這里始終為false,不會(huì)被調(diào)用

if (mBootCompleteCache.isBootComplete()) {

mServices[i].onBootCompleted();

}

}

mServicesStarted = true;

}

這里的SystemUI是一個(gè)抽象類(lèi),狀態(tài)欄、近期任務(wù)等等模塊都是繼承自SystemUI,通過(guò)這種方式可以很大程度上簡(jiǎn)化復(fù)雜的SystemUI程序中各個(gè)子模塊創(chuàng)建方式,同時(shí)我們可以通過(guò)配置資源的方式動(dòng)態(tài)加載需要的SystemUI模塊。

SystemUI的源碼如下,方法基本都能見(jiàn)名知意,就不再介紹了。

public abstract class SystemUI implements Dumpable {

protected final Context mContext;

public SystemUI(Context context) {

mContext = context;

}

public abstract void start();

protected void onConfigurationChanged(Configuration newConfig) {

}

@Override

public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {

}

protected void onBootCompleted() {

}

2.3 CarSystemUI 的啟動(dòng)流程

前文提到CarSystemUI復(fù)用了手機(jī)SystemUI的代碼,所以CarSystemUI的啟動(dòng)流程和SystemUI的是完全一致的。

但CarSystemUI中需要的功能與SystemUI中也有部分差異,那么是這些差異化的功能是如何引入并完成初始化?以及一些手機(jī)的SystemUI才需要的功能是如何去除的呢?

其實(shí)很簡(jiǎn)單,在SystemUI的啟動(dòng)流程中我們得知,各個(gè)子模塊的 className 是通過(guò)SystemUIFactory的getSystemUIServiceComponents()獲取到的,那么只要繼承SystemUIFactory并重寫(xiě)getSystemUIServiceComponents()就可以了。

public class CarSystemUIFactory extends SystemUIFactory {

@Override

protected SystemUIRootComponent buildSystemUIRootComponent(Context context) {

return DaggerCarSystemUIRootComponent.builder()

.contextHolder(new ContextHolder(context))

.build();

}

@Override

public String[] getSystemUIServiceComponents(Resources resources) {

Set names = new HashSet<>();

// 先引入systemUI中的components

for (String s : super.getSystemUIServiceComponents(resources)) {

names.add(s);

}

// 再移除CarsystemUI不需要的components

for (String s : resources.getStringArray(R.array.config_systemUIServiceComponentsExclude)) {

names.remove(s);

}

// 最后再添加CarsystemUI特有的components

for (String s : resources.getStringArray(R.array.config_systemUIServiceComponentsInclude)) {

names.add(s);

}

String[] finalNames = new String[names.size()];

names.toArray(finalNames);

return finalNames;

}

}

com.android.systemui.recents.Recents

com.android.systemui.volume.VolumeUI

com.android.systemui.stackdivider.Divider

com.android.systemui.statusbar.phone.StatusBar

com.android.systemui.keyboard.KeyboardUI

com.android.systemui.pip.PipUI

com.android.systemui.shortcut.ShortcutKeyDispatcher

com.android.systemui.LatencyTester

com.android.systemui.globalactions.GlobalActionsComponent

com.android.systemui.SliceBroadcastRelayHandler

com.android.systemui.statusbar.notification.InstantAppNotifier

com.android.systemui.accessibility.WindowMagnification

com.android.systemui.accessibility.SystemActions

com.android.systemui.car.navigationbar.CarNavigationBar

com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier

com.android.systemui.car.window.SystemUIOverlayWindowManager

com.android.systemui.car.volume.VolumeUI

通過(guò)以上方式,就完成了CarSystemUI子模塊的替換。

2.4 小結(jié)

總結(jié)一下,SystemUI的大致啟動(dòng)流程可以歸納如下:

SystemUI 是一個(gè) persistent 應(yīng)用,它由操作系統(tǒng)啟動(dòng),主要流程為

Android 系統(tǒng)在開(kāi)機(jī)后會(huì)創(chuàng)建 system_server 進(jìn)程,它會(huì)啟動(dòng)各種系統(tǒng)所需要的服務(wù),其中就包括 SystemUIService。SystemUIService 啟動(dòng)后進(jìn)入到應(yīng)用層 SystemUI 中,在 SystemUIApplication 它首先會(huì)初始化監(jiān)聽(tīng)ACTION_BOOT_COMPLETED 等通知,待系統(tǒng)完成啟動(dòng)后會(huì)通知各個(gè)組件 onBootCompleted。在進(jìn)入 SystemUIService 中依然執(zhí)行的 SystemUIApplication 中的startServicesIfNeeded() 方法啟動(dòng) SystemUI 中的子模塊。最終的服務(wù)啟動(dòng)邏輯都是在 SystemUIApplication 里面,并且都保存在 mServices 數(shù)組中。

三 總結(jié)

SystemUI在原生的車(chē)載 Android 系統(tǒng)是一個(gè)較為復(fù)雜的模塊,本文主要介紹了SystemUI 和CarSystemUI的功能、源碼結(jié)構(gòu)及啟動(dòng)時(shí)序,希望能幫到從事SystemUI開(kāi)發(fā)的同學(xué)。

四 參考文檔

Android 車(chē)載應(yīng)用開(kāi)發(fā)與分析(12) - SystemUI (一)

精彩鏈接

評(píng)論可見(jiàn),查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。

轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://m.gantiao.com.cn/post/18543071.html

發(fā)布評(píng)論

您暫未設(shè)置收款碼

請(qǐng)?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問(wèn)

文章目錄