Desenvolvimento e análise de aplicativos Android para automóveis - análise de "função" e "estrutura de código-fonte" do SystemUI

Nos vídeos e artigos anteriores, apresentamos os conhecimentos básicos necessários para todo o desenvolvimento de aplicativos Android para veículos:

  1. [Transcrição do vídeo] Desenvolvimento e análise de aplicativos Android montados em veículos - No sistema operacional montado em veículos - Nuggets
  2. [Transcrição do vídeo] Desenvolvimento e análise de aplicativos Android de veículos - download e compilação AOSP - Nuggets
  3. [Transcrição do vídeo] Desenvolvimento e análise de aplicativos automotivos Android - Desenvolvimento de aplicativos de sistema - Nuggets
  4. [Transcrição do vídeo] Desenvolvimento e análise de aplicativos Android montados em veículos - Prática e empacotamento de AIDL (Parte 1) - Nuggets
  5. [Transcrição do vídeo] Desenvolvimento e análise de aplicativos Android montados em veículos - Prática e empacotamento de AIDL (Parte 2) - Nuggets

No início desta edição, apresentaremos a implementação de aplicativos veiculares no Android Automotive nativo e seus princípios. A primeira coisa que quero apresentar é um aplicativo de sistema muito importante no desenvolvimento de aplicativos veiculares, a UI do sistema Android - SystemUI.

Como o sistema Android nativo SystemUIpossui uma grande quantidade de código e um conteúdo muito complexo, selecionarei aqui SystemUImódulos que são de referência para o desenvolvimento de veículos e os apresentarei. Haverá cerca de 4 a 5 edições de conteúdo, que são divididas principalmente em os seguintes módulos:

  1. SystemUI "Função" e "Estrutura do código-fonte"
  2. O princípio de implementação da "barra de navegação" e "barra de status" do SystemUI,
  3. O princípio de implementação da SystemUI "Barra de Notificação" e "Controle Rápido"
  4. Princípio de implementação das "Tarefas recentes" do SystemUI

Portanto, nesta edição, vamos primeiro analisar a “função” e a “estrutura do código-fonte” do SystemUI. Você pode obter os seguintes benefícios ao ler esta edição:

  1. entenda o que éSystemUI
  2. Entenda SystemUIquais são as principais funções implementadas no
  3. Entenda SystemUIa estrutura do código-fonte
  4. Entenda SystemUIcomo ele é iniciado pelo sistema e sua sequência de inicialização.

Introdução ao SystemUI

No sistema Android, SystemUIé um APP de nível de sistema, que fornece a interface do usuário do sistema e system_serveré iniciado pelo processo.

SystemUINão pertence ao processo em si system_server, é um processo independente. Sua IHM inclui barra de status, barra de navegação, barra de notificação, tela de bloqueio, tarefas recentes, etc.

SystemServer é um programa iniciado pelo processo Zogyte, responsável por iniciar e gerenciar diversos serviços principais do sistema Android. Por exemplo: ActivityManagerService e PackageManagerService, esses serviços também rodam no processo system_server, disponibilizando diversas funções e interfaces para o sistema Android ser chamado por aplicações e outros serviços. O Android Framework que costumamos dizer é, na verdade, composto por esses serviços.

Introdução à função SystemUI

SystemUIEsta parte apresentará principalmente os módulos que são de valor de referência quando personalizamos os nossos .

  • Barra de status

StatusBar é responsável por exibir informações de status como hora, energia, sinais e notificações.

  • Barra de navegação

NavigationBar exibe botões como retornar, página inicial e tarefas recentes. No Android automotivo, costumamos chamá-lo de Dock Bar (DockBar). Geralmente é responsável por exibir controles de atalho e entradas para funções comumente usadas, como controle do carro, página inicial e chamadas telefônicas Bluetooth.

  • Barra de notificação

NotificationPanel, uma interface para exibir e controlar notificações. Em projetos reais de automóveis, a barra de notificação e o [Centro de Mensagens] são frequentemente mesclados em um APP independente.

  • Controle rápido

QuickSettings, este painel permite aos usuários ajustar rapidamente algumas configurações comumente usadas, como brilho, modo avião, Bluetooth, etc. O painel QS possui vários estados, incluindo o painel primário expandido (Configurações rápidas rápidas, QQS) e o painel QS completo (Configurações rápidas, QS). Os usuários podem abrir ou fechar o painel QS puxando para baixo a barra de notificação.

  • Outras funções

Algumas caixas de diálogo de nível de sistema, janelas pop-up, animações, protetores de tela, etc. Esses conteúdos são relativamente simples e não serão introduzidos novamente. Algumas funções, como tela de bloqueio e controle de mídia, não estão muito envolvidas no desenvolvimento do SystemUI no veículo e não serão introduzidas novamente.

Estrutura do código-fonte SystemUI

SystemUIA localização do código-fonte depende da versão do Android e do tipo de dispositivo que você está usando. Este vídeo é baseado no código-fonte do Android 13 para análise.

Localização e estrutura do código-fonte SystemUI

O código-fonte do Android 13 SystemUIestá localizado no diretório ** frameworks/base/packages/SystemUI **.

SystemUIO código-fonte é composto principalmente de arquivos Java e XML. Os arquivos Java implementam SystemUIvárias funções e lógicas, e os arquivos XML definem SystemUIa interface e os recursos. SystemUIO código fonte também contém alguns testes, ferramentas, documentos e outros arquivos auxiliares. SystemUIA estrutura do código-fonte é a seguinte:

  • animação: contém algumas classes e recursos relacionados à animação.
  • verificações: contém algumas ferramentas de verificação e formatação de código.
  • compose: contém alguns componentes de interface escritos usando Jetpack Compose.
  • customização: Contém algumas classes e recursos para customização do SystemUI.
  • docs: Contém alguma documentação e documentação.
  • monet: Contém algumas classes e recursos para implementação do tema Material.
  • plugin: Contém algumas classes e interfaces para implementação de funções de plug-in.
  • plugin_core: Contém algumas classes e interfaces básicas usadas para suportar funções de plug-in.
  • res: Contém alguns arquivos de recursos comuns, como layouts, imagens, strings, etc.
  • res-keyguard: Contém alguns arquivos de recursos para a interface da tela de bloqueio.
  • res-product: Contém alguns arquivos de recursos para um produto ou dispositivo específico.
  • captura de tela: contém algumas classes e recursos para funcionalidade de captura de tela.
  • scripts: Contém alguns arquivos de script usados ​​para compilar ou executar SystemUI.
  • compartilhado: Contém classes e interfaces para compartilhamento com outros aplicativos ou módulos.
  • src: Contém os principais arquivos de código fonte do SystemUI, classificados de acordo com funções ou módulos, como barra de status, barra de navegação, notificação, proteção de teclado, recentes, etc.
  • src-debug: Contém alguns arquivos de código-fonte para depuração ou teste do SystemUI.
  • src-release: Contém alguns arquivos de código-fonte usados ​​para liberar ou otimizar SystemUI.
  • testes: contém alguns arquivos de código-fonte usados ​​para testar ou verificar o SystemUI.
  • ferramentas: Contém alguns arquivos de ferramentas para desenvolver ou analisar SystemUI.
  • desdobrar: Contém algumas classes e recursos para suporte a dispositivos de tela dobrável.

Estrutura do código-fonte CarSystemUI

O código-fonte do carro SystemUIestá localizado no diretório ** /packages/apps/Car/SystemUI **, CarSystemUIque é para SystemUIreutilização e expansão. CarSystemUIA estrutura do código-fonte é a seguinte:

  • res: Contém alguns arquivos de recursos comuns, como layouts, imagens, strings, etc.

  • res-keyguard: Contém alguns arquivos de recursos para a interface da tela de bloqueio.

  • samples: Contém recursos de skinning para CarSystemUI, principalmente usando o mecanismo RRO do Android.

  • src: Contém os principais arquivos de código fonte do CarSystemUI, classificados de acordo com funções ou módulos, como barra de status, barra de navegação, notificação, proteção de teclado, recentes, etc. Alguns desses arquivos são modificações ou extensões de arquivos com o mesmo nome no SystemUI, e alguns são novos arquivos usados ​​para implementar funções ou lógica exclusivas de equipamentos montados em veículos.

    • carro: Contém algumas classes e recursos usados ​​para suportar funções ou lógicas exclusivas de equipamentos automotivos, como CarSystemUIFactory, CarNavigationBarController, CarStatusBarController, etc.
    • wm: Contém algumas classes e recursos para gerenciar o modo e layout da janela, como SplitScreenController, PipController, TaskStackListenerImpl, etc.
    • wmshell: Contém algumas classes e recursos usados ​​para fornecer funções de shell de janela, como WmShellImpl, WmShellModule, WmShellStartableModule, etc.
    • Outros subdiretórios e arquivos: Exceto os três subdiretórios acima, outros subdiretórios e arquivos são basicamente iguais ou semelhantes aos do SystemUI, exceto por algumas modificações ou extensões para dispositivos montados em veículos. Por exemplo, a classe StatusBar não exibe o ícone da bateria no dispositivo do carro, mas exibe o ícone da gasolina.
  • testes: contém alguns arquivos de código-fonte usados ​​para testar ou verificar CarSystemUI

Modifique e compile SystemUI

Executado no diretório raiz do código-fonte do Android mm SystemUI, compilará o módulo SystemUI e suas dependências. Se você modificou outros módulos, como frameworks/base, também poderá executá-lo mm framework-minus-apexpara compilar o módulo do framework.

Após a conclusão da compilação, você pode usar o comando adb para enviar o novo SystemUI.apk para o dispositivo e reiniciar o processo SystemUI. Os comandos específicos são os seguintes:

adb root
adb remount
adb push out/target/product/emulator_x86/system_ext/priv-app/CarSystemUI/CarSystemUI.apk /system_ext/priv-app/CarSystemUI/
adb shell ps -lef | grep systemui
adb shell kill <pid>

Se o simulador exibir um prompt somente leitura ao executar o comando de remontagem, você precisará primeiro fechar o simulador e usar o comando a seguir para iniciá-lo.

emulator -writable-system -netdelay none -netspeed full
adb root
adb remount
adb reboot // 重启模拟器

Sequência de inicialização do SystemUI

SystemUIA sequência de inicialização refere-se ao SystemUIprocesso de carregamento e inicialização de um aplicativo do sistema durante a inicialização do sistema Android.

Processo de inicialização do SystemUI

Quando o sistema Android for iniciado, system_servero processo ActivityManagerServiceiniciará um serviço chamado com.android.systemui.SystemUIService.EsteSystemUI serviço é a classe de entrada e herda a classe Service.

Localização do código-fonte do SystemServer: /frameworks/base/services/java/com/android/server/SystemServer.java

  mActivityManagerService.systemReady(() -> {
            Slog.i(TAG, "Making services ready");
            //...
            t.traceBegin("StartSystemUI");
            try {
                startSystemUi(context, windowManagerF);
            } catch (Throwable e) {
                reportWtf("starting System UI", e);
            }
            t.traceEnd();
        }, t);

A partir daqui podemos ver que SystemUIé essencialmente um Serviço, e o Componente obtido através do Pm é com.android.systemui/.SystemUIService . Os detalhes do código startSystemUi são os seguintes:

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

O acima é SystemUIo processo de inicialização. A seguir, continuaremos a ver SystemUIcomo inicializar.

Processo de inicialização do SystemUI

SystemUIO processo de inicialização é dividido nas seguintes etapas:

  1. Inicialização do aplicativo

Localização do código-fonte do SystemUIApplication: /frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java

Após a inicialização, o método onCreate do Aplicativo será primeiro chamado e inicializado SystemUIno método onCreate . SystemUIAqui eu divido em quatro partes.

  • primeira parte
@Override
public void onCreate() {
    super.onCreate();
    Log.v(TAG, "SystemUIApplication created.");
    // TimingsTraceLog 是一个用于跟踪代码执行时间的工具类,它可以在traceview中看到。
    TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming",Trace.TRACE_TAG_APP);
    log.traceBegin("DependencyInjection");
    // 此行用于设置Dagger的依赖注入,并应保持在onrecate方法的顶部。
    mInitializer = mContextAvailableCallback.onContextAvailable(this);
    mSysUIComponent = mInitializer.getSysUIComponent();
    // BootCompleteCacheImpl 是一个用于缓存 BOOT_COMPLETED 广播的实现类。
    mBootCompleteCache = mSysUIComponent.provideBootCacheImpl();
    log.traceEnd();

    // 设置主线程Looper的traceTag,这样就可以在traceview中看到主线程的消息处理情况了。
    Looper.getMainLooper().setTraceTag(Trace.TRACE_TAG_APP);
    // 设置所有服务继承的应用程序主题。请注意,仅在清单中设置应用程序主题仅适用于活动。请将其与在那里设置的主题同步。
    setTheme(R.style.Theme_SystemUI);
    ...见第二部分
}

A primeira parte não contém muito conteúdo, envolve principalmente obter alguns componentes criados no SystemUI através do Dagger e configurar algumas ferramentas de depuração.

  • a segunda parte

Primeiro determine se o processo atual pertence ao usuário do sistema . SystemUIEntão, de acordo com a prioridade de contexto do renderizador definida pela configuração de prioridade de contexto da GPU SF , o último SystemServerfichário aberto chama o rastreamento de rastreamento.

@Override
public void onCreate() {
    super.onCreate();
    ...见第一部分
    // 判断当前进程是否是系统进程。如果是系统进程,那么就注册 BOOT_COMPLETED 广播接收器。
    if (Process.myUserHandle().equals(UserHandle.SYSTEM)) {
        // 创建 BOOT_COMPLETED 广播接收器的意图过滤器。
        IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
        bootCompletedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);

        // 如果SF GPU上下文优先级设置为实时,则SysUI应以高优先级运行。优先级默认为中等。
        int sfPriority = SurfaceControl.getGPUContextPriority();
        Log.i(TAG, "Found SurfaceFlinger's GPU Priority: " + sfPriority);
        if (sfPriority == ThreadedRenderer.EGL_CONTEXT_PRIORITY_REALTIME_NV) {
            Log.i(TAG, "Setting SysUI's GPU Context priority to: "+ ThreadedRenderer.EGL_CONTEXT_PRIORITY_HIGH_IMG);
            // 设置SysUI的GPU上下文优先级为高。
            ThreadedRenderer.setContextPriority(ThreadedRenderer.EGL_CONTEXT_PRIORITY_HIGH_IMG);
            // ThreadedRenderer可以简单理解为一个渲染器,它可以在后台线程中渲染视图层次结构。优先级越高,渲染速度越快。
        }
        // 在system_server上为源自SysUI的调用启用trace跟踪
        try {
            ActivityManager.getService().enableBinderTracing();
        } catch (RemoteException e) {
            Log.e(TAG, "Unable to enable binder tracing", e);
        }
        ...见第三部分
    } else {
        ...见第四部分
    }
}

ThreadedRendererPode ser entendido simplesmente como um renderizador que renderiza a hierarquia de visualizações em um thread de segundo plano. Quanto maior a prioridade, mais rápida será a velocidade de renderização. Para sua função específica, você pode consultar: Uma breve introdução à compreensão da aceleração de hardware Android - Nuggets

Process.myUserHandle()Você pode obter o tipo de usuário do processo atual. Se você estiver envolvido no desenvolvimento de aplicativos móveis, o mecanismo multiusuário do sistema Android raramente estará envolvido. No entanto, como um carro é uma ferramenta com atributos compartilhados, vários membros da família podem usar um carro, portanto, multiusuários do Android são mais comuns no desenvolvimento de veículos Android.

Quando adicionamos um novo usuário em "Sistema" e "Multiusuário" nas configurações do sistema e mudamos para esse novo usuário, outro SystemUIprocesso será realmente iniciado. O ID do usuário do novo SystemUIprocesso começará a partir de U1X , o usuário do SystemUI original O ID é sempre U0 .

Em relação aos multiusuários do Android, você pode consultar as informações oficiais: Suporte a multiusuários - Android Também escreverei um blog separado posteriormente para explicar o mecanismo multiusuário do sistema Android.

  • a terceira parte

Registre-se para ouvir a transmissão de inicialização e, após SystemUIServicea inicialização, notifique SystemUIoutros componentes do sistema de que "a inicialização do sistema foi concluída".

        // 注册 BOOT_COMPLETED 广播接收器。
        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();
                // 判断SystemUIService是否启动
                if (mServicesStarted) {
                    final int N = mServices.length;
                    for (int i = 0; i < N; i++) {
                    // 通知SystemUI中各个组件,系统启动完成。
                        mServices[i].onBootCompleted();
                    }
                }
            }
        }, bootCompletedFilter);

        // Intent.ACTION_LOCALE_CHANGED 是系统语言发生变化时发送的广播。
        IntentFilter localeChangedFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
        registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
                    if (!mBootCompleteCache.isBootComplete()) return;
                    // 更新SystemUi通知通道的名称
                    NotificationChannels.createAll(context);
                }
            }
        }, localeChangedFilter);
  • quarta parte

Se o usuário atual não for um usuário do sistema , chame o método startSecondaryUserServicesIfNeeded.

    } else {
        // 我们不需要为正在执行某些任务的子进程初始化组件。例如:截图进程等
        String processName = ActivityThread.currentProcessName();
        ApplicationInfo info = getApplicationInfo();
        if (processName != null && processName.startsWith(info.processName + ":")) {
            return;
        }
        // 对于第二个用户,boot-completed永远不会被调用,因为它已经在启动时为主SystemUI进程广播了
        // 对于需要每个用户初始化SystemUI组件的组件,我们现在为当前非系统用户启动这些组件。
        startSecondaryUserServicesIfNeeded();
    }

SystemUIO método startSecondaryUserServicesIfNeeded também inicializa os componentes funcionais por meio do método startServicesIfNeeded . Analisaremos como inicializá-lo especificamente mais tarde.

void startSecondaryUserServicesIfNeeded() {
    // 对startables进行排序,以便我们获得确定的顺序。
    Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>(Comparator.comparing(Class::getName));
    sortedStartables.putAll(mSysUIComponent.getPerUserStartables());
    startServicesIfNeeded(sortedStartables, "StartSecondaryServices", null);
}

Neste ponto, vamos resumir brevemente SystemUIApplicationas tarefas mais importantes. Na verdade, existem apenas duas:

① Um componente funcional que monitora a transmissão de inicialização no espaço do usuário do sistema e o notifica .SystemUI

② No espaço do usuário que não é do sistema, os componentes funcionais são inicializados diretamente.SystemUI

  1. Iniciar SystemUIService

Depois que o aplicativo concluir a inicialização, o SystemUIService será iniciado imediatamente.

Localização do código-fonte do SystemUIService: /frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java

SystemUIServiceNo método onCreate(), o método ((SystemUIApplication) getApplication()).startServicesIfNeeded() será chamado

@Override
public void onCreate() {
    super.onCreate();
    // Start all of SystemUI
    ((SystemUIApplication) getApplication()).startServicesIfNeeded();
    ...
}

Pode haver uma pergunta aqui: Por que não escrever a lógica relevante de startServicesIfNeeded no Serviço em vez de escrevê-la no Aplicativo?

Isso ocorre porque quando o usuário atual não é um usuário do sistema , startSecondaryUserServicesIfNeeded também precisa chamar o método startServicesIfNeeded para inicializar o componente, então basta escrever toda a lógica de inicialização na Aplicação.

public void startServicesIfNeeded() {
    // vendorComponent 是一个字符串,它的值是:com.android.systemui.VendorServices
    // com.android.systemui.VendorServices 是一个空类,它的作用是在SysUI启动时,启动一些第三方服务。
    final String vendorComponent = mInitializer.getVendorComponent(getResources());

    // 对startables进行排序,以便我们获得确定的顺序
    // TODO: make #start idempotent and require users of CoreStartable to call it.
    Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>(
            Comparator.comparing(Class::getName));
    sortedStartables.putAll(mSysUIComponent.getStartables());
    sortedStartables.putAll(mSysUIComponent.getPerUserStartables());
    startServicesIfNeeded(sortedStartables, "StartServices", vendorComponent);
}
  • Antes do Android 13

Este método usará reflexão para criar e iniciar uma série de serviços com base nas definições do arquivo de configuração config_systemUIServiceComponents ou config_systemUIServiceComponentsPerUser , como , , , etc. Cada um desses serviços estende uma interface chamada SystemUI .SystemUIStatusBarNavigationBarNotificationPanelKeyguard

SystemUIUm contexto será fornecido para eles, e os retornos de chamada onConfigurationChanged e onBootCompleted serão fornecidos para eles. Esses serviços são SystemUIos componentes principais e são responsáveis ​​por fornecer diversas funções e interfaces.

  • Android 13 e posterior

Um novo é adicionado vendorComponent, vendorComponent é uma string, seu valor é: com.android.systemui.VendorServices. VendorServicesHerdado, CoreStartablemas sem qualquer implementação interna, o objetivo do design do Google é que ele possa ser usado para iniciar alguns serviços de terceiros quando o SysUI for iniciado.

Antes do Android 13, cada SystemUIserviço também dependia da Dependencyinjeção de dependência personalizada fornecida pela classe para obter alguns SystemUIobjetos que abrangem o ciclo de vida. Mas depois do Android 13, SystemUIa criação de componentes funcionais e a injeção de dependência são concluídas automaticamente pelo Dagger.

private void startServicesIfNeeded(Map<Class<?>, Provider<CoreStartable>> startables,String metricsPrefix,String vendorComponent) {
    if (mServicesStarted) {
        return;
    }
    mServices = new CoreStartable[startables.size() + (vendorComponent == null ? 0 : 1)];

    if (!mBootCompleteCache.isBootComplete()) {
        // 检查BOOT_COMPLETED是否已经发送。如果是这样,我们不需要等待它。
        // 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.Entry<Class<?>, Provider<CoreStartable>> entry : startables.entrySet()) {
        String clsName = entry.getKey().getName();
        int j = i;  // Copied to make lambda happy.
        // timeInitialization 记录初始化的时间
        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;
}

Sobre como usar o Dagger no SystemUI do Android13. Você pode ler a documentação oficial: frameworks/base/packages/SystemUI/docs/dagger.md

Vamos resumir SystemUIServicenovamente o processo de inicialização, que pode ser resumido nas quatro etapas a seguir:

①Chame o método startServicesIfNeeded em SystemUIApplication

② O método startServicesIfNeeded obtém os componentes funcionais criados do SystemUI por meio do Dagger e os classifica de acordo com o nome do pacote e o nome da classe.

③Chame o método start() do componente funcional SystemUI em sequência e registre o tempo gasto.

④Ao receber a transmissão BOOT_COMPLETED ou verificar se a inicialização foi concluída na SystemProperty, o onBootCompleted() do componente funcional é chamado em sequência para completar a inicialização.SystemUI SystemUI

Resumir

Nesta edição, apresentamos brevemente SystemUIas funções, estrutura do código-fonte e sequência de inicialização do sistema Android.

Recentemente, tanto os vídeos quanto as atualizações do blog têm sido muito lentos, o motivo é que postei uma descrição dinâmica na estação B. Devido às demissões, terei que passar mais tempo no trabalho por um bom tempo.

Ok, obrigado pela leitura, espero que seja útil para você e nos vemos na próxima edição.

Acho que você gosta

Origin blog.csdn.net/linkwj/article/details/131590001
Recomendado
Clasificación