當前位置:首頁 » 安卓系統 » android啟動分析

android啟動分析

發布時間: 2024-07-06 08:18:13

A. Android —— Activity的四種啟動模式

除了Activity的生命周期外,Activity的啟動模式也是一個難點,有時候為了滿足項目的特殊需求,就必須使用Activity的啟動模式。

在默認情況下,當我們多次啟動同一個Activity的時候,系統會創建多個實例並把它們放入任務棧中,但是有些場景重復創建多個實例,是沒有必要且浪費資源的,這就需要啟動模式來修改系統的默認行為。

下面,我將以理論+實踐的形式為大家介紹Activity的啟動模式。

這是系統的默認啟動模式,採用這種模式的Activity無論是否已經存在實例,都會重新創建一個實例,在這種模式下誰啟動了這個Activity,那麼這個Activity就運行在啟動它的那個Activity所在的棧中。

實踐:MainActivity 採用 standard 模式

在這種模式下,如果新的Activity已經位於任務棧的棧頂,那麼此Activity不會被重新創建,同時它的 NewIntent 方法將會被回調。如果新Activity的實例已存在但不是位於棧頂,那麼新Activity依然會被創建。

實踐:MainActivity 採用 singleTop 模式

MainActivity 採用 singleTop 模式,SecondActivity採用 standard 模式

這是一種單實例模式,在這種模式下,只要Activity在一個棧中存在,那麼多次啟動此Activity都不會重新創建實例,而是回調 onNewIntent() 。

實踐:MainActivity 採用 singleTask 模式

MainActivity 採用 singleTask 模式,SecondActivity採用 standard 模式

這是一種加強的 singleTask 模式,它除了具有 singleTask 模式的所有特性外,還加強了一點,那就是具有此模式的Activity只能單獨的位於一個任務棧中。

實踐:MainActivity 採用 singleInstance 模式

MainActivity 採用 singleInstance 模式,SecondActivity採用 standard 模式

以上就是Activity啟動模式的介紹。

歡迎留言指出錯誤。

B. 如何優化 android 系統應用的啟動速度

一、應用的啟動

啟動方式

通常來說,在安卓中應用的啟動方式分為兩種:冷啟動和熱啟動。

  • 1、冷啟動:當啟動應用時,後台沒有該應用的進程,這時系統會重新創建一個新的進程分配給該應用,這個啟動方式就是冷啟動。

  • 2、熱啟動:當啟動應用時,後台已有該應用的進程(例:按back鍵、home鍵,應用雖然會退出,但是該應用的進程是依然會保留在後台,可進入任務列表查看),所以在已有進程的情況下,這種啟動會從已有的進程中來啟動應用,這個方式叫熱啟動。

  • 特點

    1、冷啟動:冷啟動因為系統會重新創建一個新的進程分配給它,所以會先創建和初始化Application類,再創建和初始化MainActivity類(包括一系列的測量、布局、繪制),最後顯示在界面上。

    2、熱啟動:熱啟動因為會從已有的進程中來啟動,所以熱啟動就不會走Application這步了,而是直接走MainActivity(包括一系列的測量、布局、繪制),所以熱啟動的過程只需要創建和初始化一個MainActivity就行了,而不必創建和初始化Application,因為一個應用從新進程的創建到進程的銷毀,Application只會初始化一次。

    上面說的啟動是點擊app的啟動圖標來啟動的,而另外一種方式是進入最近使用的列表界面來啟動應用,這種不應該叫啟動,應該叫恢復。

    二、應用啟動的流程

    安卓系統上,應用在沒有進程的情況下,應用的啟動都是這樣一個流程:當點擊app的啟動圖標時,安卓系統會從Zygote進程中fork創建出一個新的進程分配給該應用,之後會依次創建和初始化Application類、創建MainActivity類、載入主題樣式Theme中的windowBackground等屬性設置給MainActivity以及配置Activity層級上的一些屬性、再inflate布局、當onCreate/onStart/onResume方法都走完了後最後才進行contentView的measure/layout/draw顯示在界面上,所以直到這里,應用的第一次啟動才算完成,這時候我們看到的界面也就是所說的第一幀。

    所以,總結一下,應用的啟動流程如下:

    Application的構造器方法——>attachBaseContext()——>onCreate()——>Activity的構造方法——>onCreate()——>配置主題中背景等屬性——>onStart()——>onResume()——>測量布局繪制顯示在界面上。

    三、測量應用啟動的時間

    在上面這個啟動流程中,任何一個地方有耗時操作都會拖慢我們應用的啟動速度,而應用啟動時間是用毫秒度量的,對於毫秒級別的快慢度量我們還是需要去精確的測量到到底應用啟動花了多少時間,而根據這個時間來做衡量。

    什麼才是應用的啟動時間

    從點擊應用的啟動圖標開始創建出一個新的進程直到我們看到了界面的第一幀,這段時間就是應用的啟動時間。

    我們要測量的也就是這段時間,測量這段時間可以通過adb shell命令的方式進行測量,這種方法測量的最為精確,命令為:

  • adb shell am start -W [packageName]/[packageName.MainActivity]

  • 執行成功後將返回三個測量到的時間:
    1、ThisTime:一般和TotalTime時間一樣,除非在應用啟動時開了一個透明的Activity預先處理一些事再顯示出主Activity,這樣將比TotalTime小。
    2、TotalTime:應用的啟動時間,包括創建進程+Application初始化+Activity初始化到界面顯示。
    3、WaitTime:一般比TotalTime大點,包括系統影響的耗時。

    下面是測量一個應用冷啟動和熱啟動的時間:
    冷啟動:

    熱啟動:

    以上就是本文的全部內容,希望對大家學習Android軟體編程有所幫助。

C. Android系統啟動之init.rc文件解析過程

第一篇: Android系統啟動之bootloader
第二篇: Android系統啟動之Init流程(上)
第三篇: Android系統啟動之Init流程(下)
第四篇: Android系統啟動之init.rc文件解析過程
第五篇: Android系統啟動之zyogte進程
第六篇: Android系判嘩統啟動之zyogte進程java(上)
第七篇: Android系統啟動之zyogte進程java(下)
第八篇: Android系統啟動之SystemServer

Android init.rc文件由系統第一個啟動的init程序解析。是啟動系統服務使用的文件。

主要包含了四種類型的語句:

Action和services顯式聲明了一個語句塊,而commands和options屬於最近聲明的語句塊。

在第一個語句塊之前 的commands和options會被忽略.

基本規則如下:

動掘螞行作表示了一組命令(commands)組成.動作包括一個觸發器,決定了何時運行這個動作。

注意: 當觸發器的條件滿足時,這個動作會被增加到已被運行的隊列尾。假設此動作在隊列中已經存在,那麼它將不會運行.

一個動作所包括的命令將被依次運行。

在"動作"(action)裡面的,on後面物隱跟著的字元串是觸發器(trigger),trigger是一個用於匹配某種事件類型的字元串,它將對應的Action的執行。

觸發器(trigger)有幾種格式:

常見的格式:

command是action的命令列表中的命令,或者是service中的選項 onrestart 的參數命令.

命令將在所屬事件發生時被一個個地執行.

常見命令:

服務是指那些須要在系統初始化時就啟動或退出時自己主動重新啟動的程序.

解釋一下各個參數:

options是Service的修訂項。它們決定一個服務何時以及如何運行.

使用例子:

源碼路徑 system/core/init/init.cpp 中:

開始解析rc文件.

ParseConfig函數在文件 core/init/init_parser.cpp 140行:

ParseConfigFile函數:

Android init.rc文件淺析
安卓系統啟動--3init.rc解析
init.rc深入學習

D. Android啟動過程深入解析

當按下Android設備電源鍵時究竟發生了什麼?

Android的啟動過程是怎麼樣的?

什麼是linux內核?

桌面系統linux內核與Android系統linux內核有什麼區別?

什麼是引導裝載程序?

什麼是Zygote?

什麼是X86以及ARM linux?

什麼是init.rc?

什麼是系統服務?

當我們想到Android啟動過程時,腦海中總是冒出很多疑問。本文將介紹Android的啟動過程,希望能幫助你找到上面這些問題的答案。

Android是一個基於Linux的開源操作系統。x86(x86是一系列的基於intel 8086 CPU的計算機微處理器指令集架構)是linux內核部署最常見的系統。然而,所有的Android設備都是運行在ARM處理器(ARM 源自進階精簡指令集機器,源自ARM架構)上,除了英特爾的Xolo設備(http://xolo.in/xolo-x900-features)。Xolo來源自凌動1.6GHz x86處理器。Android設備或者嵌入設備或者基於linux的ARM設備的啟動過程與桌面版本相比稍微有些差別。這篇文章中,我將解釋Android設備的啟動過程。深入linux啟動過程是一篇講桌面linux啟動過程的好文。

當你按下電源開關後Android設備執行了以下步驟。

此處圖片中step2中的一個單詞拼寫錯了,Boot Loaeder應該為Boot Loader(多謝@jameslast 提醒)

第一步:啟動電源以及系統啟動

當電源按下,引導晶元代碼開始從預定義的地方(固化在ROM)開始執行。載入引導程序到RAM,然後執行。

第二步:引導程序

引導程序是在Android操作系統開始運行前的一個小程序。引導程序是運行的第一個程序,因此它是針對特定的主板與晶元的。設備製造商要麼使用很受歡迎的引導程序比如redboot、uboot、qi bootloader或者開發自己的引導程序,它不是Android操作系統的一部分。引導程序是OEM廠商或者運營商加鎖和限制的地方。

引導程序分兩個階段執行。第一個階段,檢測外部的RAM以及載入對第二階段有用的程序;第二階段,引導程序設置網路、內存等等。這些對於運行內核是必要的,為了達到特殊的目標,引導程序可以根據配置參數或者輸入數據設置內核。

Android引導程序可以在找到。

傳統的載入器包含的個文件,需要在這里說明:

init.s初始化堆棧,清零BBS段,調用main.c的_main()函數;

main.c初始化硬體(鬧鍾、主板、鍵盤、控制台),創建linux標簽。

更多關於Android引導程序的可以在這里了解。

第三步:內核

Android內核與桌面linux內核啟動的方式差不多。內核啟動時,設置緩存、被保護存儲器、計劃列表,載入驅動。當內核完成系統設置,它首先在系統文件中尋找」init」文件,然後啟動root進程或者系統的第一個進程。

第四步:init進程

init是第一個進程,我們可以說它是root進程或者說有進程的父進程。init進程有兩個責任,一是掛載目錄,比如/sys、/dev、/proc,二是運行init.rc腳本

init進程可以在/system/core/init找到。

init.rc文件可以在/system/core/rootdir/init.rc找到。

readme.txt可以在/system/core/init/readme.txt找到。

對於init.rc文件,Android中有特定的格式以及規則。在Android中,我們叫做Android初始化語言。

Action(動作):動作是以命令流程命名的,有一個觸發器決定動作是否發生。

語法

1

2

3

4

5

; html-script: false ]

on <trigger>

<command>

<command>

<command>

Service(服務):服務是init進程啟動的程序、當服務退出時init進程會視情況重啟服務。

語法

1

2

3

4

5

; html-script: false ]

service <name> <pathname> [<argument>]*

<option>

<option>

...

Options(選項)

選項是對服務的描述。它們影響init進程如何以及何時啟動服務。

咱們來看看默認的init.rc文件。這里我只列出了主要的事件以及服務。

Table

Action/Service

描述

on early-init

設置init進程以及它創建的子進程的優先順序,設置init進程的安全環境

on init

設置全局環境,為cpu accounting創建cgroup(資源控制)掛載點

on fs

掛載mtd分區

on post-fs

改變系統目錄的訪問許可權

on post-fs-data

改變/data目錄以及它的子目錄的訪問許可權

on boot

基本網路的初始化,內存管理等等

service servicemanager

啟動系統管理器管理所有的本地服務,比如位置、音頻、Shared preference等等…

service zygote

啟動zygote作為應用進程

在這個階段你可以在設備的屏幕上看到「Android」logo了。

第五步

在Java中,我們知道不同的虛擬機實例會為不同的應用分配不同的內存。假如Android應用應該盡可能快地啟動,但如果Android系統為每一個應用啟動不同的Dalvik虛擬機實例,就會消耗大量的內存以及時間。因此,為了克服這個問題,Android系統創造了」Zygote」。Zygote讓Dalvik虛擬機共享代碼、低內存佔用以及最小的啟動時間成為可能。Zygote是一個虛擬器進程,正如我們在前一個步驟所說的在系統引導的時候啟動。Zygote預載入以及初始化核心庫類。通常,這些核心類一般是只讀的,也是Android SDK或者核心框架的一部分。在Java虛擬機中,每一個實例都有它自己的核心庫類文件和堆對象的拷貝。

Zygote載入進程

載入ZygoteInit類,源代碼:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

registerZygoteSocket()為zygote命令連接注冊一個伺服器套接字。

preloadClassed 「preloaded-classes」是一個簡單的包含一系列需要預載入類的文本文件,你可以在/frameworks/base找到「preloaded-classes」文件。

preloadResources() preloadResources也意味著本地主題、布局以及android.R文件中包含的所有東西都會用這個方法載入。

在這個階段,你可以看到啟動動畫。

第六步:系統服務或服務

完成了上面幾步之後,運行環境請求Zygote運行系統服務。系統服務同時使用native以及java編寫,系統服務可以認為是一個進程。同一個系統服務在Android SDK可以以System Services形式獲得。系統服務包含了所有的System Services。

Zygote創建新的進程去啟動系統服務。你可以在ZygoteInit類的」startSystemServer」方法中找到源代碼。

核心服務:

啟動電源管理器;

創建Activity管理器;

啟動電話注冊;

啟動包管理器;

設置Activity管理服務為系統進程;

啟動上下文管理器;

啟動系統Context Providers;

啟動電池服務;

啟動定時管理器;

啟動感測服務;

啟動窗口管理器;

啟動藍牙服務;

啟動掛載服務。

其他服務:

啟動狀態欄服務;

啟動硬體服務;

啟動網路狀態服務;

啟動網路連接服務;

啟動通知管理器;

啟動設備存儲監視服務;

啟動定位管理器;

啟動搜索服務;

啟動剪切板服務;

啟動登記服務;

啟動壁紙服務;

啟動音頻服務;

啟動耳機監聽;

啟動AdbSettingsObserver(處理adb命令)。

第七步:引導完成

一旦系統服務在內存中跑起來了,Android就完成了引導過程。在這個時候「ACTION_BOOT_COMPLETED」開機啟動廣播就會發出去。

E. Android系統的幾種啟動模式

1.一般啟動模式(normal mode) 進入方法:按電源鍵啟動 描述:這是正常啟動手機的方法 2.安全模式(safe mode) 進入方法:按住menu鍵,按電源鍵啟動手機,直至手機啟動完成松開menu鍵 描述:和正常啟動一樣,但沒有登記Google,所以不能訪問Market或使用你的Google賬號 3.引導模式(bootloader mode) 進入方法:按住照相鍵,按電源鍵啟動手機 描述:可以從SD卡上安裝新的系統映像(DREAIMG.NBH),只需再按一次電源鍵。為獲取root許可權,對手機進行降級,就是使用這個模式。 4.恢復模式(recovery mode) 進入方法:按住HOME鍵,按電源鍵啟動手機 描述:可以打開命令解釋程序(shell),刷新映像文件(flash image),執行備份等。當然這一切取決於你手機上的recovery image版本。 5.診斷模式(diagnostic mode) 進入方法:按住軌跡球,按電源鍵啟動手機 描述:用於測試(按音量鍵選擇項目) 6.fastboot模式 進入方法:按住返回鍵,按電源鍵啟動手機,直至屏幕出現FASTBOOT字樣後松開返回鍵

F. Android Activity啟動模式與狀態保存及恢復詳解

       Activity是 Android組件 中最基本也是最為常見用的四大組件(Activity,Service服務,Content Provider內容提供者,BroadcastReceiver廣播接收器)之一 。
       Activity是一個應用程序 組件 ,提供一個 屏幕 ,用戶可以用來交互為了完成某項任務。
       Activity中所有操作都與用戶密切相關,是一個負責與 用戶交互 的組件,可以通過setContentView(View)來 顯示指定控制項
       在一個android應用中,一個Activity通常就是一個單獨的屏幕,它上面可以顯示一些控制項也可以監聽並處理用戶的事件做出響應。Activity之間通過Intent進行通信。
       關於Activity啟動流程請參考之前的文章 Android activity啟動流程分析

       activity有四種啟動模式,分別為standard,singleTop,singleTask,singleInstance。如果要使用這四種啟動模式,必須在manifest文件中<activity>標簽中的launchMode屬性中配置。

       標準的默認啟動模式,這種模式下activity可以被多次實例化,即在一個task中可以存在多個activity,每一個activity會處理一個intent對象,(在A中再次啟動A,會存在後面的A在前面的A上面,當前task會存在兩個activity的實例對象)

       如果一個singleTop模式啟動的activity實例已經存在於棧頂,那麼再次啟動這個activity的時候,不會重新創建實例,而是重用位於棧頂的那個實例,並且會調用實例的onNewIntent()方法將Intent對象傳遞到這個實例中,如果實例不位於棧頂,會創建新的實例。

       啟動模式設置為singleTask,framework在啟動該activity時只會把它標示為可在一個新任務中啟動,至於是否在一個新任務中啟動,還要受其他條件的限制,即taskAffinity屬性。
        taskAffinity :默認情況下,一個應用中的所有activity具有相同的taskAffinity,即應用程序的包名。我們可以通過設置不同的taskAffinity屬性給應用中的activity分組,也可以把不同的應用中的activity的taskAffinity設置成相同的值,當兩個不同應用中的activity設置成相同的taskAffinity時,則兩個activity會屬於同一個TaskRecord。
       在啟動一個singleTask的Activity實例時,如果系統中已經存在這樣一個實例,就會將這個實例調度到任務棧的棧頂,並清除它當前所在任務中位於它上面的所有的activity;如果這個已存在的任務中不存在一個要啟動的Activity的實例,則在這個任務的頂端啟動一個實例;若這個任務不存在,則會啟動一個新的任務,在這個新的任務中啟動這個singleTask模式的Activity的一個實例。

       以singleInstance模式啟動的Activity具有全局唯一性,即整個系統中只會存在一個這樣的實例,如果在啟動這樣的Activiyt時,已經存在了一個實例,那麼會把它所在的任務調度到前台,重用這個實例。
       以singleInstance模式啟動的Activity具有獨占性,即它會獨自佔用一個任務,被他開啟的任何activity都會運行在其他任務中(官方文檔上的描述為,singleInstance模式的Activity不允許其他Activity和它共存在一個任務中)。
       被singleInstance模式的Activity開啟的其他activity,能夠開啟一個新任務,但不一定開啟新的任務,也可能在已有的一個任務中開啟,受條件的限制,這個條件是:當前系統中是不是已經有了一個activity B的taskAffinity屬性指定的任務。

       涉及到Activity啟動,就不得不說一下Activity的管理,Activity是以什麼方式及被什麼類來進行管理的,涉及的類主要如下:

       歷史棧中的一個條目,代表一個activity。ActivityRecord中的成員變數task表示其所在的TaskRecord,ActivityRecord與TaskRecord建立了聯系。

       內部維護一個 ArrayList<ActivityRecord> 用來保存ActivityRecord,TaskRecord中的mStack表示其所在的ActivityStack,TaskRecord與ActivityStack建立了聯系。

       內部維護了一個 ArrayList<TaskRecord> ,用來管理TaskRecord,ActivityStack中持有ActivityStackSupervisor對象,由ActivityStackSupervisor創建。

       負責所有ActivityStack的管理。內部管理了mHomeStack、mFocusedStack和mLastFocusedStack三個Activity棧。其中,mHomeStack管理的是Launcher相關的Activity棧;mFocusedStack管理的是當前顯示在前台Activity的Activity棧;mLastFocusedStack管理的是上一次顯示在前台Activity的Activity棧。

       ActivityThread 運行在UI線程(主線程),App的真正入口。

       用來實現AMS和ActivityThread之間的交互。

       負責調用Activity和Application生命周期。

       當一個Activity未被主動關閉,即「被動關閉」時,可能需要系統給用戶提供保持一些狀態的入口。

       前面說的入口就是:Activity提供了onSaveInstanceState()方法,該方法是Activity在關閉前保存狀態的核心方法。

       前面提到「被動關閉」,如果是主動關閉那麼就不會調用,比如:按back鍵、調用finish()等,那麼"被動關閉"的場景有哪些呢?下面給列舉一下:

       肯定在調用onStop()前被調用,但不保證在onPause()前 / 後,一般是在onPause()後調用。

       當需要保持狀態時,在onSaveInstanceState()內執行以下邏輯:

       當需要恢復時,在onCreate()內部執行以下邏輯:

       布局每個View默認實現:onSaveInstanceState(),即UI的任何改變都會自動的存儲和在activity重新創建的時候自動的恢復(只有在為該UI提供了唯一ID後才起作用);
       若需復寫該方法從而存儲額外的狀態信息時,應先調用父類的onSaveInstanceState()(因為默認的onSaveInstanceState()幫助UI存儲它的狀態);
       只使用該方法記錄Activity的瞬間狀態(UI的狀態),而不是去存儲持久化數據,因為onSaveInstanceState()調用時機不確定性;可使用 onPause()[一定會執行]存儲持久化數據;

       Activity提供了onRestoreInstanceState()方法,該方法是Activity在重新創建後恢復之前保存狀態的核心方法。

       若被動關閉了Activity,即調用了onSaveInstanceState(),那麼下次啟動時會調用onRestoreInstanceState()。

       onCreate()--->onStart()--->onRestoreInstanceState()--->onResume()

        注意: onSaveInstanceState()、onRestoreInstanceState()不一定 成對被調用
       如:當正在顯示Activity A時,用戶按下HOME鍵回到主界面,然後用戶緊接著又返回到Activity A,此時Activity A一般不會因為內存的原因被系統銷毀,故Activity A的onRestoreInstanceState()不會被執行;
       針對以上情況,onSaveInstanceState保持的參數可以選擇在onCreate()內部進行解析使用,因為onSaveInstanceState的bundle參數會傳遞到onCreate方法中,可選擇在onCreate()中做數據還原。
        至此:Activity的啟動模式及Activity的狀態保持及恢復介紹完畢。

熱點內容
數獨游戲編程 發布:2024-11-26 06:16:08 瀏覽:584
平板鎖屏密碼是什麼 發布:2024-11-26 06:16:06 瀏覽:218
安卓怎麼看應用程序數量 發布:2024-11-26 06:11:51 瀏覽:376
海信u7a怎麼調出配置 發布:2024-11-26 06:06:05 瀏覽:90
無法查找伺服器ip地址 發布:2024-11-26 06:03:34 瀏覽:539
租用雲伺服器需要專業知識嗎 發布:2024-11-26 05:58:04 瀏覽:560
明日之後榴彈炮武器如何配置 發布:2024-11-26 05:49:59 瀏覽:497
商賽中演算法 發布:2024-11-26 05:48:28 瀏覽:291
校園論壇源碼 發布:2024-11-26 05:42:35 瀏覽:568
民生銀行pin密碼是多少 發布:2024-11-26 05:31:24 瀏覽:775