Launcher啟動流程&&載入流程學習
宣告: 圖片本來是有的 涉及到有些程式碼不能示人沒有貼上,不過僅文字說也足夠了,請廣大老爺們自行下載原始碼參看流程分析閱讀。
目錄
一、 認識Launcher:
1、功能
① Launcher是Android系統的啟動器
② 應用程式的管理器
③ Android系統的桌面
2、樣式
① 原生Launcher3經典的四種UI模式
從Launcher桌面元素的角度來看,元件包括應用程式的快捷方式、資料夾、桌面小部件及相關元件,稱這類元件為桌面元件。
3、Android.mk檔案
以上我們認識了其從功能到介面的瞭解,下面就是我們程式設計師上場的時候了
LOCAL_MODULE_TAGS := optional
// 編譯選項為何種模式編譯,optional為在任種模式下均可編譯(User、eng、test三種模式)
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_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 :
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
//編譯Launcher3時Launcher2不會被加入編譯系統
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檔案,如果有則啟動一次編譯
3、AndroidManifest檔案
①許可權:
<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第一次載入的時候會向系統發一次廣播,如果對此感興趣則需要申請該許可權。
② 應用程式元件配置:
Launcher3主Activity配置
宣告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)呼叫各service的systemready介面,啟動service。這些service基本都是單例類,所以這種註冊也是方便全域性呼叫。
1、 從Systemserver到AMS
SystemServer.Java
路徑:/frameworks/base/services/java/com/android/server/SystemServer.java
之後在
方法中檢查時間、地區、語言環境,首先判斷系統當前時間,若當前時間小於1970年1月1日,則一些初始化操作可能會處所,所以當系統的當前時間小於1970年1月1日的時候,設定系統當前時間為該時間點。
······
上面的主要是設定虛擬機器執行記憶體,載入執行庫,設定SystemServer的非同步訊息
可知可以看到在SystemServer程序中也存在著Context物件,然後通過SystemServiceManager的構造方法建立了一個新的SystemServiceManager物件,我們知道SystemServer程序主要是用來構建系統各種service服務的,而SystemServiceManager就是這些服務的管理物件。
裡面主要涉及了是三個方法:startBootstrapServices() 主要用於啟動系統Boot級服務startCoreServices() 主要用於啟動系統核心的服務startOtherServices() 主要用於啟動一些非緊要或者是非需要及時啟動的服務
1、BootstrapServices為引導服務,啟動的service包括:Installer 系統安裝apk時的一個服務類,啟動完成Installer服務之後才能啟動其他的系統服務ActivityManagerService 負責四大元件的啟動、切換、排程。PowerManagerService 計算系統中和Power相關的計算,然後決策系統應該如何反應LightsService 管理和顯示背光LEDDisplayManagerService 用來管理所有顯示裝置UserManagerService 多使用者模式管理SensorService 為系統提供各種感應器服務PackageManagerService 用來對apk進行安裝、解析、刪除、解除安裝等等操作
2、CoreServices為核心服務,包括:BatteryService 管理電池相關的服務UsageStatsService 收集使用者使用每一個APP的頻率、使用時常WebViewUpdateService WebView更新服務
3、OtherServices其他服務,包括很多服務,比如:CameraService 攝像頭相關服務AlarmManagerService 全域性定時器管理服務InputManagerService 管理輸入事件WindowManagerService 視窗管理服務VrManagerServiceVR模式管理服務BluetoothService 藍芽管理服務NotificationManagerService 通知管理服務DeviceStorageMonitorService 儲存相關管理服務LocationManagerService 定位管理服務AudioService 音訊相關管理服務
······
模組SystemUI啟動···
接下來我們轉移戰地到ActivityManagerService中
2 將SystemServer程序加到AMS中排程管理
ActivityManagerService.java
/frameworks /base/services/core/java/com/android/server/am/ActivityManagerService.java
······
· setSystemProcess意義:
這一步就是給SystemServer程序建立ProcessRecord,adj值,就是將SystemServer程序加入到AMS程序管理機制中,跟應用程序一致;
3 AMS systemReady過程
······
4 啟動HomeActivity
······
getHomeIntent函式中建立了Intent,並將mTopAction和mTopData傳入。mTopAction的值為Intent.ACTION_MAIN,並且如果系統執行模式不是低階工廠模式則將intent的Category設定為Intent.CATEGORY_HOME。我們再回到ActivityManagerService的startHomeActivityLocked函式,假設系統的執行模式不是低階工廠模式,符合Action為Intent.ACTION_MAIN,Category為Intent.CATEGORY_HOME的應用程式是否已經啟動
這個被啟動的應用程式就是Launcher,因為Launcher的Manifest檔案中的intent-filter標籤匹配了Action為Intent.ACTION_MAIN,Category為Intent.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:圖示快取類,應用程式icon和title的快取,內部類建立了資料庫app_icons.db。
LauncherProvider:核心資料庫類,負責launcher.db的建立與維護。
LauncherAppWidgetHost:AppWidgetHost子類,是桌面外掛宿主,為了方便託拽等才繼承處理的。
LauncherAppWidgetHostView:AppWidgetHostView子類,配合LauncherAppWidgetHost得到HostView。
LauncherRootView:豎屏模式下根佈局,繼承了InsettableFrameLayout,控制是否顯示在狀態列等下面。
DragLayer:一個用來負責分發事件的ViewGroup。
DragController:DragLayer只是一個ViewGroup,具體的拖拽的處理都放到了DragController中。
BubblTextView:圖示都基於他,繼承自TextView。
DragView:拖動圖示時跟隨手指移動的View。
Folder:開啟資料夾展示的View。
FolderIcon:資料夾圖示。
DragSource/DropTarget:拖拽介面,DragSource表示圖示從哪開始拖,DropTarget表示圖示被拖到哪去。
ItemInfo:桌面上每個Item的資訊資料結構,包括在第幾屏、第幾行、第幾列、寬高等資訊;該物件與資料庫中記錄一一對應;該類有多個子類,譬如FolderIcon的FolderInfo、BubbleTextView的ShortcutInfo等。
2.流程
App的啟動是從Application開始的,但是我們最新的Launcher3中,谷歌工程師把這個類移除,再次之前的版本都是有這個類的
我們手頭的LauncherApplication了,現在講解的是基於最新的Launcher3程式碼,因此我們這個Launcher中沒有Application,所以程式啟動最開始的是ContentProvider的onCreate方法,程式碼如下:
/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上的內容
並沒有直接進行載入,只是對一些狀態進行了更新和條件判斷,loadWorkspace和bindWorkspace才是實際操作。
我們看真正的載入WorkSpace。程式碼敲長的~
初始化後面要用到的物件例項
······
/Launcher3/src/com/android/launcher3/LauncherProvider.java
如果資料庫還沒有建立,就會載入預設的配置(default_workspace_xxx.xml),並儲存到資料庫中。
······
在載入過後就要開始綁定了。
先是各種初始化以及各物件的例項化
······
執行runnable裡面回撥在Launcher中的方法準備進行繫結
然後是真正的繫結
和startBinding類似
·······
······
同樣呼叫Launcher的回撥
以及類似的bindWorkspaceItems、bindAddScreens、bindFolders、bindAppWidget是運用的同樣的套路。載入資料夾、item、空白頁等有大量的細節,感興趣可以跟蹤程式碼。(不行了,累死了,不想寫了···)
最後通知其繫結完成。
這樣整個loadAndBindWorkspace過程就結束了,接著下一步。
② 載入繫結Allapps中的內容
第二步:loadAndBindAllApps
······
······
依舊是回撥Launcher.Java中的回撥方法
小結:
1.獲取需要顯示到Launcher中的app列表,建立app圖示 |
2.繫結app—bindAllApplications
至此 Allapps也載入繫結結束。
接著會執行onPackagesUpdated,package的更新操作,就不再展開了。Widget也是類似的。這樣載入allapp的過程就結束了。
回到launcher的Oncreate方法。
在這裡執行第一次開機的使用者嚮導(可定製化)
③ 總結
最後,借用一張圖來總結其從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開發者,也要緊跟步伐去學習,把好的實現