1. 程式人生 > >Launcher啟動流程&&載入流程學習

Launcher啟動流程&&載入流程學習

 宣告: 圖片本來是有的 涉及到有些程式碼不能示人沒有貼上,不過僅文字說也足夠了,請廣大老爺們自行下載原始碼參看流程分析閱讀。

目錄

1、功能 1

2、樣式 2

①許可權: 5

總結 25

一、 認識Launcher

1、功能

① LauncherAndroid系統的啟動器

② 應用程式的管理器

③ Android系統的桌面

 

2、樣式

① 原生Launcher3經典的四種UI模式

 

Launcher桌面元素的角度來看,元件包括應用程式的快捷方式、資料夾、桌面小部件及相關元件,稱這類元件為桌面元件。

3Android.mk檔案

以上我們認識了其從功能到介面的瞭解,下面就是我們程式設計師上場的時候了

LOCAL_MODULE_TAGS := optional

// 編譯選項何種模式編譯,optional為在任種模式下均可編譯(Userengtest三種模式)

LOCAL_SRC_FILES := $(call all-java-files-under, src) \

    $(call all-java-files-under, WallpaperPicker/src) \

$(call all-proto-files-under, protos)

//需要編譯的資原始檔

LOCAL_RESOURCE_DIR :

= $(LOCAL_PATH)/WallpaperPicker/res $(LOCAL_PATH)/res

//需要編譯的資原始檔的路徑

LOCAL_PROGUARD_FLAG_FILES := proguard.flags

//用於混淆程式碼的指令碼檔名該處為proguard.flags(出於程式碼安全考慮的混淆工具可配置)

LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 android-support-v7-recyclerview

//需要依賴的Java

LOCAL_PROTOC_OPTIMIZE_TYPE := nano

LOCAL_PROTOC_FLAGS :

= --proto_path=$(LOCAL_PATH)/protos/

LOCAL_AAPT_FLAGS := --auto-add-overlay

//應用程式打包標示變數,設定為自動新增並覆蓋

#LOCAL_SDK_VERSION := current

LOCAL_PACKAGE_NAME := Launcher3

LOCAL_PRIVILEGED_MODULE := true

#LOCAL_CERTIFICATE := shared

LOCAL_OVERRIDES_PACKAGES := Home Launcher2

//編譯Launcher3Launcher2不會被加入編譯系統

include $(BUILD_PACKAGE)

//當完成了本地編譯環境變數的設定以後,通過該語句啟動編譯,生成目標

#

# Protocol Buffer Debug Utility in Java

#配置工具庫依賴編譯

include $(CLEAR_VARS)

LOCAL_SRC_FILES := $(call all-java-files-under, util) \

    $(call all-proto-files-under, protos)

LOCAL_PROTOC_OPTIMIZE_TYPE := nano

LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/

LOCAL_MODULE_TAGS := optional

LOCAL_MODULE := launcher_protoutil_lib

LOCAL_IS_HOST_MODULE := true

LOCAL_JAR_MANIFEST := util/etc/manifest.txt

include $(BUILD_HOST_JAVA_LIBRARY)

#

# Protocol Buffer Debug Utility Wrapper Script

# Protocol Buffer的測試工具

include $(CLEAR_VARS)

LOCAL_IS_HOST_MODULE := true

LOCAL_MODULE_CLASS := EXECUTABLES

LOCAL_MODULE_TAGS := optional

LOCAL_MODULE := launcher_protoutil

include $(BUILD_SYSTEM)/base_rules.mk

$(LOCAL_BUILT_MODULE): | $(HOST_OUT_JAVA_LIBRARIES)/launcher_protoutil_lib.jar

$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/util/etc/launcher_protoutil | $(ACP)

@echo "Copy: $(PRIVATE_MODULE) ([email protected])"

$(copy-file-to-new-target)

$(hide) chmod 755 [email protected]

INTERNAL_DALVIK_MODULES += $(LOCAL_INSTALLED_MODULE)

include $(call all-makefiles-under,$(LOCAL_PATH))

//這是一個遞迴的呼叫,意思是搜尋Launcher3目錄下是否還有其他的Android.mk檔案,如果有則啟動一次編譯

3AndroidManifest檔案

①許可權:

<permission

        android:name="com.android.launcher.permission.INSTALL_SHORTCUT"

  //安裝快捷方式

        android:name="com.android.launcher3.permission.READ_SETTINGS"

        android:name="com.android.launcher3.permission.WRITE_SETTINGS"

                android:name="com.android.launcher3.permission.RECEIVE_LAUNCH_BROADCASTS"

//Launcher3對外提供一個內容提供者,應用程式可以通過鑑權資訊來訪問資料,為此讀寫這些資料時會申請該許可權

android:name="com.android.launcher3.permission.RECEIVE_FIRST_LOAD_BROADCAST"

//Launcher3第一次載入的時候會向系統發一次廣播,如果對此感興趣則需要申請該許可權。

② 應用程式元件配置:

Launcher3Activity配置

 

宣告Launcher是一個單任務模式的Activity

<action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.HOME" />

兩句尤為重要,體現了Launcher的特殊地位,說明這是桌面

桌布桌面選擇模組的配置

 

二、 啟動流程

先從SystemServer開始。

systemserver最主要的作用:

1) 就是初始化framework層各種service和其對應的特定servicemanager,並將他們註冊到全域性servicemanager,以便其他地方只需要通過servicemanager. getService(String servicename)就可以取得該service的例項。

2)  2)呼叫各servicesystemready介面,啟動service這些service基本都是單例類,所以這種註冊也是方便全域性呼叫。

1 SystemserverAMS

SystemServer.Java

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

 

之後在

 

 

方法中檢查時間、地區、語言環境,首先判斷系統當前時間,若當前時間小於197011日,則一些初始化操作可能會處所,所以當系統的當前時間小於197011日的時候,設定系統當前時間為該時間點。

······

 


面的主要是設定虛擬機器執行記憶體,載入執行庫,設定SystemServer的非同步訊息

 

 

可知可以看到在SystemServer程序中也存在著Context物件,然後通過SystemServiceManager的構造方法建立了一個新的SystemServiceManager物件,我們知道SystemServer程序主要是用來構建系統各種service服務的,而SystemServiceManager就是這些服務的管理物件。

 

裡面主要涉及了是三個方法:startBootstrapServices() 主要用於啟動系統Boot級服務startCoreServices() 主要用於啟動系統核心的服務startOtherServices() 主要用於啟動一些非緊要或者是非需要及時啟動的服務

1BootstrapServices為引導服務,啟動的service包括:Installer 系統安裝apk時的一個服務類,啟動完成Installer服務之後才能啟動其他的系統服務ActivityManagerService 負責四大元件的啟動、切換、排程。PowerManagerService 計算系統中和Power相關的計算,然後決策系統應該如何反應LightsService 管理和顯示背光LEDDisplayManagerService 用來管理所有顯示裝置UserManagerService 多使用者模式管理SensorService 為系統提供各種感應器服務PackageManagerService 用來對apk進行安裝、解析、刪除、解除安裝等等操作

2CoreServices為核心服務,包括:BatteryService 管理電池相關的服務UsageStatsService 收集使用者使用每一個APP的頻率、使用時常WebViewUpdateService WebView更新服務

3OtherServices其他服務,包括很多服務,比如:CameraService 攝像頭相關服務AlarmManagerService 全域性定時器管理服務InputManagerService 管理輸入事件WindowManagerService 視窗管理服務VrManagerServiceVR模式管理服務BluetoothService 藍芽管理服務NotificationManagerService 通知管理服務DeviceStorageMonitorService 儲存相關管理服務LocationManagerService 定位管理服務AudioService 音訊相關管理服務

 

······

 

 模組SystemUI啟動···

接下來我們轉移戰地到ActivityManagerService

SystemServer程序加到AMS中排程管理

ActivityManagerService.java

/frameworks /base/services/core/java/com/android/server/am/ActivityManagerService.java

 

······

 

·  setSystemProcess意義:

    這一步就是給SystemServer程序建立ProcessRecord,adj值,就是將SystemServer程序加入到AMS程序管理機制中,跟應用程序一致;

3 AMS systemReady過程

 

······

 

啟動HomeActivity

 

······

 


getHomeIntent函式中建立了Intent,並將mTopActionmTopData傳入。mTopAction的值為Intent.ACTION_MAIN,並且如果系統執行模式不是低階工廠模式則將intentCategory設定為Intent.CATEGORY_HOME。我們再回到ActivityManagerServicestartHomeActivityLocked函式,假設系統的執行模式不是低階工廠模式,符合ActionIntent.ACTION_MAINCategoryIntent.CATEGORY_HOME的應用程式是否已經啟動

這個被啟動的應用程式就是Launcher,因為LauncherManifest檔案中的intent-filter標籤匹配了ActionIntent.ACTION_MAINCategoryIntent.CATEGORY_HOME。這樣,應用程式Launcher就會被啟動起來,並執行它的onCreate函式。

/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

ActivityStackSupervisor.java

 

一張圖總結Launcher啟動流程:

 

三、 載入流程

在上述的Launcher啟動流程已經理清之後,我們接下來就可以進行對Launcher的載入捋捋了。

1.重要類認識

首先對一些檔案進行認識。

Launcher:主介面Activity,最核心且唯一的Activity

LauncherAppState:單例物件,構造方法中初始化物件、註冊應用安裝、解除安裝、更新,配置變化等廣播。這些廣播用來實時更新桌面圖示等,其receiver的實現在LauncherModel類中,LauncherModel也在這裡初始化。

LauncherModel:資料處理類,儲存桌面狀態,提供讀寫資料庫API,內部類LoaderTask用來初始化桌面。

InvariantDeviceProfile:一些不變的裝置相關引數管理類,其內部包涵了橫豎屏模式的DeviceProfile

WidgetPreviewLoader:儲存Widget資訊的資料庫,內部建立了資料庫widgetpreviews.db

LauncherAppsCompat:獲取已安裝App列表資訊的相容抽象基類,子類依據不同版本API進行相容性處理。

AppWidgetManagerCompat:獲取AppWidget列表的相容抽象基類,子類依據不同版本API進行相容性處理。

LauncherStateTransitionAnimation:各類動畫總管處理執行類,負責各種情況下的各種動畫效果處理。

IconCache:圖示快取類,應用程式icontitle的快取,內部類建立了資料庫app_icons.db

LauncherProvider:核心資料庫類,負責launcher.db的建立與維護。

LauncherAppWidgetHostAppWidgetHost子類,是桌面外掛宿主,為了方便託拽等才繼承處理的。

LauncherAppWidgetHostViewAppWidgetHostView子類,配合LauncherAppWidgetHost得到HostView

LauncherRootView:豎屏模式下根佈局,繼承了InsettableFrameLayout,控制是否顯示在狀態列等下面。

DragLayer:一個用來負責分發事件的ViewGroup

DragControllerDragLayer只是一個ViewGroup,具體的拖拽的處理都放到了DragController中。

BubblTextView:圖示都基於他,繼承自TextView

DragView:拖動圖示時跟隨手指移動的View

Folder:開啟資料夾展示的View

FolderIcon:資料夾圖示。

DragSource/DropTarget:拖拽介面,DragSource表示圖示從哪開始拖,DropTarget表示圖示被拖到哪去。

ItemInfo:桌面上每個Item的資訊資料結構,包括在第幾屏、第幾行、第幾列、寬高等資訊;該物件與資料庫中記錄一一對應;該類有多個子類,譬如FolderIconFolderInfoBubbleTextViewShortcutInfo等。

2.流程

App的啟動是從Application開始的,但是我們最新的Launcher3,谷歌工程師把這個類移除,再次之前的版本都是有這個類的

們手頭的LauncherApplication了,現在講解的是基於最新的Launcher3程式碼,因此我們這個Launcher中沒有Application,所以程式啟動最開始的是ContentProvideronCreate方法,程式碼如下:

/alps/packages/apps/Launcher3/src/com/android/launcher3/LauncherProvider.java

LauncherProvider.java

嚴苛模式:

1. 啟用嚴苛模式,StrictMode可以用於捕捉髮生在應用程式主執行緒中耗時的磁碟、網路訪問或函式呼叫,  

2. 可以幫助開發者使其改程序序,使主執行緒處理UI和動畫在磁碟讀寫和網路操作時變得更平滑,避免主執行緒被阻塞,導致ANR視窗的發生。  

程式碼中處理的事情不多,主要是啟動嚴苛模式和建立資料庫

接下來就是啟動Launcher,我麼看一下Launcher中的onCreate方法中的程式碼:

/alps/packages/apps /Launcher3/src/com/android/launcher3/Launcher.java

Launcher.java

 

······

 

······

 

 

這一段程式碼是用來非同步載入桌面的應用快捷圖示、小部件和所有應用圖標,是最重要的一步

./Launcher3/src/com/android/launcher3/LauncherModel.java

LauncherModel.java

 

執行run方法。

 

① 載入繫結Workspace上的內容

 

並沒有直接進行載入,只是對一些狀態進行了更新和條件判斷,loadWorkspacebindWorkspace才是實際操作。

我們看真正的載入WorkSpace。程式碼敲長的~

 

初始化後面要用到的物件例項

······

 

/Launcher3/src/com/android/launcher3/LauncherProvider.java

 

如果資料庫還沒有建立,就會載入預設的配置(default_workspace_xxx.xml),並儲存到資料庫中。

······

在載入過後就要開始綁定了

 

先是各種初始化以及各物件的例項化

······

執行runnable裡面回撥在Launcher中的方法準備進行繫結

 


然後是真正的繫結

startBinding類似

 

·······

 

······

同樣呼叫Launcher的回撥

 

以及類似的bindWorkspaceItemsbindAddScreensbindFoldersbindAppWidget是運用的同樣的套路。載入資料夾、item、空白頁等有大量的細節,感興趣可以跟蹤程式碼。(不行了,累死了,不想寫了···)

最後通知其繫結完成。

 


這樣整個loadAndBindWorkspace過程就結束了,接著下一步。

② 載入繫結Allapps中的內容

第二步:loadAndBindAllApps

 


······

 

······

 

依舊是回撥Launcher.Java中的回撥方法

小結:

1.獲取需要顯示到Launcher中的app列表,建立app圖示

2.繫結app—bindAllApplications

至此 Allapps也載入繫結結束。

接著會執行onPackagesUpdatedpackage的更新操作,就不再展開了。Widget也是類似的。這樣載入allapp的過程就結束了。

回到launcherOncreate方法。

 

在這裡執行第一次開機的使用者嚮導(可定製化)

③ 總結

最後,借用一張圖來總結其從Oncreate以來的執行步驟。

相關推薦

Launcher啟動流程&&載入流程學習

 宣告: 圖片本來是有的 涉及到有些程式碼不能示人沒有貼上,不過僅文字說也足夠了,請廣大老爺們自行下載原始碼參看流程分析閱讀。 目錄 1、功能 1 2、樣式 2 ①許可權: 5 ③總結 25 一、 認識Launcher: 1、功能

Android Launcher啟動應用程式流程原始碼解析

帶著問題看原始碼 點選桌面Launcher圖示後做了哪些工作? 應用程式什麼時候被建立的? Application和MainActivity的onCreate()方法什麼時候被呼叫的? 概述 在Android系統中,啟動四大元件中的任何一個都可以啟動應用程式。但絕大部分時候我們是通過點選Laun

Android Framework學習(四)之Launcher啟動流程解析

在之前的部落格中,我們學習了init程序、Zygote程序和SyetemServer程序的啟動過程,我們知道SystemServer程序主要用於啟動系統的各種服務,二者其中就包含了負責啟動Launcher的服務,LauncherAppService,本篇部落格我

Android學習歷程--Launcher整體載入流程總結

本文為自己學習思路的總結若有需要或整理詳細程式碼及細節 一、進入  LauncherApplication -> LauncherAppState -> 進行初始化環境(通過傳遞sContext)、進行事件監聽&&初始化一些環境例如:橫豎屏、當

Nginx學習之十一-Nginx啟動框架處理流程

table ssl 優先級 init int 數組 linux cmd 默認 Nginx啟動過程流程圖 下面首先給出Nginx啟動過程的流程圖: ngx_cycle_t結構體 Nginx的啟動初始化在src/core/nginx.c的main函數中完成,當然main

Launcher中資料的載入流程

承接上一篇文章Launcher的相關知識,當我們進入startLoader方法中,看到最後有這樣一行程式碼 sWorker.post(mLoaderTask); 第一想法是開啟了子執行緒,要執行耗時操作,想想也對載入資料當然是耗時操作要開啟子執行緒。但是別急者去看runnable中

Android原始碼解析之(十)-->Launcher啟動流程

上一篇文章中我們講解了關於SystemServer程序相關的知識,我們知道SystemServer程序主要用於啟動系統的各種服務,二者其中就包含了負責啟動Launcher的服務,LauncherAppService。具體更多關於SystenServer的啟動

Android Launcher載入流程原始碼分析

Launcher載入流程分析 最近開始接手Launcher模組,為了更好的技術積累,也看到很多大神在CSDN上發的博文,就有了在CSDN寫部落格的想法,這篇博文是我在研究了一段時間Launcher3後寫的,可能有不對的,望大家拍磚。首先我們可以先參考這篇htt

【原始碼剖析】Launcher 8.0 原始碼 (1) --- Launcher 啟動流程 綜述

現在網上關於Launcher啟動流程的原始碼分析流傳最多的是google Launcher2.0的啟動流程。截止2018年5月,google Launcher已經到了8.0版本。 經對比,8.0和2.0的啟動流程大同小異,整體流程依然保留了2.0的結構特徵,以Launc

Android系統啟動流程(四)Launcher啟動過程與系統啟動流程

相關文章  Android系統架構與系統原始碼目錄  Android系統啟動流程(一)解析init程序啟動過程  Android系統啟動流程(二)解析Zygote程序啟動過程  Android系統啟動流程(三)解析SyetemServer程序啟動過程 前言

JVM的啟動載入class檔案流程

載入主類的class檔案 Java執行方式有兩種:jar方式和class方式。 + 裝載:查詢和匯入class檔案; 連線: (1)檢查:檢查載入的class檔案資料的正確性; (2)準備:為類的靜態變數分配儲存空間; (3)解析:將符號引用轉換成

Android Launcher分析和修改9——Launcher啟動APP流程

  本來想分析AppsCustomizePagedView類,不過今天突然接到一個臨時任務。客戶反饋說機器介面的圖示很難點選啟動程式,經常點選了沒有反應,Boss說要優先解決這問題。沒辦法,只能看看是怎麼回事。今天分析一下Launcher啟動APP的過程。從使用者點選到程式啟動的流程,下面針對WorkSpac

Webkit學習 ----網頁資源的構建載入流程

Webkit的作用在這就不多做介紹了,本篇主要還是個人在原始碼分析了webkit之後的心得總結!       webkit有上千個類,在這麼錯綜複雜的結構裡看流程無疑找死,好吧,用GDB除錯看吧!       環境:webkit + Qt4.8.4 + gdb

launcher 啟動應用流程簡述

在Launcher程序中,首先呼叫startActivity(),然後呼叫startActivityForResult(),然後呼叫到Instrumention的execStartActivity(),

【SylixOS】QT程式啟動載入流程簡介(一)

QT應用程式啟動載入流程簡介 QWS(Qt Windows System)是QT自行開發的視窗系統,體系結構類似X Windows的C/S結構。QWS Server在物理裝置上顯示,QWS Client實現介面,兩者通過socket進行彼此的通訊。在很多嵌入式系統裡,QT

啟動Activity的流程(Launcher中點選圖示啟動)

啟動Activity一般有多種方式,常見的有三種: 在Launcher桌面點選app圖示 呼叫startActivity啟動一個Activity 命令am start啟動 這三種方式在服務端的處理方式基本相同,客戶端的請求方式也差別

flutter原始碼學習筆記-圖片載入流程

本文基於1.12.13+hotfix.8版本原始碼分析。 #### 0、大綱 1. Image 2. ImageProvider 3. 圖片資料載入 ImageStream、ImageStreamCompleter 4. 快取池 PaintingBinding#imageCache 5. 網路圖片載入 #

CenOS/Fedora系統啟動的整個流程——符合多數linux系統

管理程序 計算機 system linux 操作系統 本文主要講述CenOS系統啟動的整個流程,同系列系統也基本相符,不同系列Linux也差不多。對於CentOS系統來說,整個啟動過程可分為4個階段,分別是:加點自檢;加載MBR;加載內核並執行初始化信息;初始化用戶空間。下面就具體來描述每

PHP應用的CI/CD流程實踐與學習:一、PHP運行環境的準備

代碼結構 php7.1 運行環境 php應用 nginx 數據卷 選擇 class tar 前言:一直以來想學習與實踐一下敏捷開發,之前項目雖說口口聲聲我們項目是敏捷開發,其實很扯。 敏捷開發如果有持續集成、持續部署的支持,那樣開發、測試、運維將節省不少精力。 此系列博

Launcher3 Workspace載入流程淺析(基於Aosp P版本)

launcher3 Workspace載入流程淺析 前言 Aosp launcher3原始碼隨著Android大版本的迭代,也在不斷的更新,大體功能變化不大,但卻在不斷的重構和優化程式碼,程式碼的封裝和擴充套件性變得越來越好,作為launcher開發者,也要緊跟步伐去學習,把好的實現