天天看點

Activity 的 36 大難點,你會幾個?「深度好文」前言文章目錄友善大家學習,我在 GitHub 上建立個 倉庫神圖一、 生命周期二、 啟動模式三、 資料四、 Context五、 程序總結

作者:_yuanhao

連結:

https://www.jianshu.com/p/86c0a4afd28e

前言

  • Android

    有一段時間了,一直都隻顧着學新的東西,最近發現很多平常用的少的東西竟讓都忘了,趁着這兩天,打算把有關

    Activity

    的内容以問題的形式梳理出來,也供大家查缺補漏。
本文中,我将一改往日寫部落格的習慣,全文用 XMind 将所有知識點以思維導圖的形式呈現,歡迎大家食用~~

文章目錄

    • *

友善大家學習,我在 GitHub 上建立個 倉庫

  • 倉庫内容與部落格同步更新。由于我在

    稀土掘金

    簡書

    CSDN

    部落格園

    等站點,都有新内容釋出。是以大家可以直接關注該倉庫,以免錯過精彩内容!
  • 倉庫位址:
    [超級幹貨!精心歸納 `Android` 、`JVM` 、算法等,各位帥氣的老鐵支援一下!給個 Star !](https://links.jianshu.com/go?to=https%3A%2F%2Fgithub.com%2FFishInWater-1999%2Fandroid_interviews)
               

神圖

  • 在開始之前,先讓我們看看

    Android

    activity

    到底都有哪些東西?
  • 借一張網上很火的圖帶你了解

    Activity

一、 生命周期

  • 先貼一張聞名遐迩的圖
  • 我們生命周期先看看具體有哪些方法回調,在逐一攻破:

1.1 Dialog 彈出時

  • 如果是單純是建立的

    dialog

    Activity

    并不會執行生命周期的方法
  • 但是如果是跳轉到一個不是全屏的

    Activity

    的話, 當然就是按照正常的生命周期來執行了
  • onPasue()

    ->

    onPause()

    ( 不會執行原

    Activity

    onStop()

    , 否則上個頁面就不顯示了 )

1.2 橫豎屏切換時

  • 不設定

    Activity

    android:configChanges

    時,切屏會重新調用各個生命周期,切橫屏時會執行一次,切豎屏時會執行兩次
  • 設定

    Activity

    android:configChanges="orientation"

    時,切屏還是會重新調用各個生命周期,切橫、豎屏時隻會執行一次
  • Activity

    android:configChanges="orientation|keyboardHidden"

    時,切屏不會重新調用各個生命周期,隻會執行

    onConfigurationChanged

    方法
  • 注意:還有一點,非常重要,一個

    Android

    的變更細節!當

    API >12

    時,需要加入

    screenSize

    屬性,否則螢幕切換時即使你設定了

    orientation

    系統也會重建

    Activity

  • 橫豎屏切換生命周期的執行

1.3 不同場景下 Activity 生命周期的變化過程

  • 啟動

    Activity

    onCreate()

    --->

    onStart()

    onResume()

    Activity

    進入運作狀态。
  • 鎖屏時會執行

    onPause()

    onStop()

    , 而開屏時則應該執行

    onStart()

    onResume()

  • Activity

    退居背景: 目前

    Activity

    轉到新的

    Activity

    界面或按

    Home

    鍵回到主屏:

    onPause()

    onStop()

    ,進入停滞狀态。
  • Activity

    傳回前台:

    onRestart()

    onStart()

    onResume()

    ,再次回到運作狀态。
  • Activity

    退居背景: 且系統記憶體不足, 系統會殺死這個背景狀态的

    Activity

    ,若再次回到這個

    Activity

    ,則會走

    onCreate()

    -->

    onStart()

    onResume()

1.4 将一個 Activity 設定成視窗的樣式

隻需要給我們的

Activity

配置如下屬性即可。

android:theme="@android:style/Theme.Dialog"

1.5 退出已調用多個 Activity 的 Application

  • 通常情況使用者退出一個

    Activity

    隻需按傳回鍵,我們寫代碼想退出

    activity

    直接調用

    finish()

    方法就行。
  • 發送特定廣播:
  1. 在需要結束應用時, 發送一個特定的廣播,每個

    Activity

    收到廣播後,關閉 即可。
  2. 給某個

    activity

    注冊接受接受廣播的意圖

    registerReceiver(receiver, filter)

  3. 如果過接受到的是 關閉

    activity

    的廣播

    activity finish()

  • 遞歸退出
  1. 就調用

    finish()

    方法 把目前的

    Activity

    退出
  2. 在打開新的

    Activity

    時使用

    startActivityForResult

    , 然後自己加标志, 在

    onActivityResult

    中處理, 遞歸關閉。
  • 其實
  1. 也可以通過

    intent

    flag

    來實作

    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)

    激活一個新的

    activity

  2. 此時如果該任務棧中已經有該

    Activity

    , 那麼系統會把這個

    Activity

    上面的所有

    Activity

    幹掉。
  3. 其實相當于給

    Activity

    配置的啟動模式為

    singleTask

  • 記錄打開的

    Activity

  1. 每打開一個

    Activity

    , 就記錄下來。
  2. 在需要退出時 , 關閉每一個

    Activity

1.6 鎖定屏與解鎖螢幕,Activity 如何執行生命周期

  • onPause()

    onStop()

    onStart()

    onResume()

1.7 修改 Activity 進入和退出動畫

  • 可以通過兩種方式 , 一是通過定義

    Activity

    的主題 ,二是通過覆寫

    Activity

    overridePendingTransition

    方法。
  • 通過設定主題樣式在

    styles.xml

    中編輯代碼 , 添加

    themes.xml

    檔案:在

    AndroidManifest.xml

    中給指定的

    Activity

    指定

    theme

  • 覆寫

    overridePendingTransition

    方法:

    overridePendingTransition(R.anim.fade, R.anim.hold)

    ;

1.8 Activity 的四種狀态

  • runnig

    :使用者可以點選,

    activity

    處于棧頂狀态。
  • paused

    activity

    失去焦點的時候,被一個非全屏的

    activity

    占據或者被一個透明的

    activity

    覆寫,這個狀态的

    activity

    并沒有銷毀,它所有的狀态資訊和成員變量仍然存在,隻是不能夠被點選。(記憶體緊張的情況,這個

    activity

    有可能被回收)
  • stopped

    :這個

    activity

    被另外一個

    activity

    完全覆寫,但是這個

    activity

    的所有狀态資訊和成員變量仍然存在(除了記憶體緊張)
  • killed

    activity

    已經被銷毀,其所有的狀态資訊和成員變量已經不存在了。

1.9 如何處理異常退出

  • Activity

    異常退出的時候 -->

    onPause()

    onSaveInstanceState()

    onStop()

    onDestory()

  • 需要注意的是

    onSaveInstanceState()

    方法與

    onPause

    并沒有嚴格的先後關系,有可能在

    onPause

    之前,也有可能在其後面調用,但會在

    onStop()

    方法之前調用
  • 異常退出後又重新啟動該

    Activity

    onCreate()

    onStart()

    onRestoreInstanceState()

    onResume()

  • 搞懂這個生命周期的執行後就可以回答了,首先要知道面試官的意思:是要重新啟動并恢複這個

    Activity

    還是說直接退出整個

    app

  • 如果要恢複則要在

    onSaveInstanceState()

    中進行儲存資料并在

    onRestoreInstanceState()

    中進行恢複
  • 如果是要退出

    app

    的話就要捕獲全局的異常資訊,并退出

    app

  • 當然個人建議是使用

    UncaughtExceotionHandler

    來捕獲全局異常進行退出

    app

    的操作,這樣會減少之前崩潰所造成的後遺症!

1.10 什麼是 onNewIntent

  • 如果

    IntentActivity

    處于任務棧的頂端,也就是說之前打開過的

    Activity

    ,現在處于

    onPause

    onStop

    狀态的話,其他應用再發送

    Intent

    的話
  • 執行順序為:

    onNewIntent

    onRestart

    onStart

    onResume

二、 啟動模式

2.1 啟動模式

  • Activity

    一共有四種

    launchMode

    standard

    singleTop

    singleTask

    singleInstance

  • Standard

    模式(預設模式)
  1. 說明: 每次啟動一個

    Activity

    都會又一次建立一個新的執行個體入棧,無論這個執行個體是否存在。
  2. 生命周期:每次被建立的執行個體

    Activity

    的生命周期符合典型情況,它的

    onCreate

    onStart

    onResume

    都會被調用。
  3. 舉例:此時

    Activity

    棧中以此有

    A

    B

    C

    三個

    Activity

    ,此時C處于棧頂,啟動模式為

    Standard

    模式。若在

    C Activity

    中加入點選事件,須要跳轉到還有一個同類型的

    C Activity

    。結果是還有一個

    C Activity

    進入棧中,成為棧頂。
  • SingleTop

    模式(棧頂複用模式)
  1. 說明:分兩種處理情況:須要建立的

    Activity

    已經處于棧頂時,此時會直接複用棧頂的

    Activity

    。不會再建立新的

    Activity

    ;若須要建立的

    Activity

    不處于棧頂,此時會又一次建立一個新的

    Activity

    入棧,同

    Standard

    模式一樣。
  2. 生命周期:若情況一中棧頂的

    Activity

    被直接複用時,它的

    onCreate

    onStart

    不會被系統調用,由于它并沒有發生改變。可是一個新的方法

    onNewIntent

    會被回調(

    Activity

    被正常建立時不會回調此方法)。
  3. Activity

    A

    B

    C

    Activity

    ,此時

    C

    處于棧頂,啟動模式為

    SingleTop

    模式。情況一:在

    C Activity

    C Activity

    。結果是直接複用棧頂的

    C Activity

    。情況二:在

    C Activity

    中加入點選事件,須要跳轉到還有一個

    A Activity

    。結果是建立一個新的

    Activity

    入棧。成為棧頂。
  • SingleTask

    模式(棧内複用模式)
  1. 說明:若須要建立的

    Activity

    已經處于棧中時,此時不會建立新的

    Activity

    ,而是将存在棧中的

    Activity

    上面的其他

    Activity

    所有銷毀,使它成為棧頂。
  2. 如果是在别的應用程式中啟動它,則會建立一個

    task

    ,并在該task中啟動這個

    Activity

    singleTask

    允許别的

    Activity

    與其在一個

    task

    中共存,也就是說,如果我在這個

    singleTask

    的執行個體中再打開新的

    Activity

    ,這個新的

    Activity

    還是會在

    singleTask

    的執行個體的

    task

    中。
  3. 生命周期:同

    SingleTop

    模式中的情況一同樣。僅僅會又一次回調

    Activity

    中的

    onNewIntent

  4. Activity

    A

    B

    C

    Activity

    。此時

    C

    SingleTask

    C Activity

    C Activity

    。結果是直接用棧頂的

    C Activity

    C Activity

    A Activity

    。結果是将

    A Activity

    上面的

    B

    C

    所有銷毀,使

    A Activity

    成為棧頂。
  • SingleInstance

    模式(單執行個體模式)
  1. 說明:

    SingleInstance

    比較特殊,是全局單例模式,是一種加強的

    SingleTask

    模式。它除了具有它所有特性外,還加強了一點:隻有一個執行個體,并且這個執行個體獨立運作在一個

    task

    中,這個

    task

    隻有這個執行個體,不允許有别的

    Activity

    存在。
  2. 這個經常使用于系統中的應用,比如

    Launch

    、鎖屏鍵的應用等等,整個系統中僅僅有一個!是以在我們的應用中一般不會用到。了解就可以。
  3. 舉例:比方

    A Activity

    是該模式,啟動

    A

    後。系統會為它建立一個單獨的任務棧,由于棧内複用的特性。興許的請求均不會建立新的

    Activity

    ,除非這個獨特的任務棧被系統銷毀。

2.2 啟動模式的使用方式

  • Manifest.xml

    中指定

    Activity

    啟動模式
  1. 一種靜态的指定方法
  2. Manifest.xml

    檔案裡聲明

    Activity

    的同一時候指定它的啟動模式
  3. 這樣在代碼中跳轉時會依照指定的模式來建立

    Activity

  • Activity

    時。在

    Intent

    中指定啟動模式去建立

    Activity

  1. 一種動态的啟動模式
  2. new

    一個

    Intent

  3. 通過

    Intent

    addFlags

    方法去動态指定一個啟動模式。
  • 注意:以上兩種方式都能夠為

    Activity

    指定啟動模式,可是二者還是有差别的。
  1. 優先級:動态指定方式即另外一種比第一種優先級要高,若兩者同一時候存在,以另外一種方式為準。
  2. 限定範圍:第一種方式無法為

    Activity

    直接指定

    FLAG_ACTIVITY_CLEAR_TOP

    辨別,另外一種方式無法為

    Activity

    singleInstance

    模式。

2.3 啟動模式的實際應用場景

這四種模式中的

Standard

模式是最普通的一種,沒有什麼特别注意。而

SingleInstance

模式是整個系統的單例模式,在我們的應用中一般不會應用到。是以,這裡就具體解說

SingleTop

SingleTask

模式的運用場景:
  • SingleTask

    模式的運用場景
  1. 最常見的應用場景就是保持我們應用開啟後僅僅有一個

    Activity

    的執行個體。
  2. 最典型的樣例就是應用中展示的首頁(

    Home

    頁)。
  3. 假設使用者在首頁跳轉到其他頁面,運作多次操作後想傳回到首頁,假設不使用

    SingleTask

    模式,在點選傳回的過程中會多次看到首頁,這明顯就是設計不合理了。
  • SingleTop

  1. 假設你在目前的

    Activity

    中又要啟動同類型的

    Activity

  2. 此時建議将此類型

    Activity

    的啟動模式指定為

    SingleTop

    ,能夠降低Activity的建立,節省記憶體!
  • 注意:複用

    Activity

    時的生命周期回調
  1. 這裡還須要考慮一個

    Activity

    跳轉時攜帶頁面參數的問題。
  2. 由于當一個

    Activity

    設定了

    SingleTop

    或者

    SingleTask

    模式後,跳轉此

    Activity

    出現複用原有

    Activity

    的情況時,此

    Activity

    onCreate

    方法将不會再次運作。

    onCreate

    方法僅僅會在第一次建立

    Activity

    時被運作。
  3. 而一般

    onCreate

    方法中會進行該頁面的資料初始化、

    UI

    初始化,假設頁面的展示資料無關頁面跳轉傳遞的參數,則不必操心此問題
  4. 若頁面展示的資料就是通過

    getInten()

    方法來擷取,那麼問題就會出現:

    getInten()

    擷取的一直都是老資料,根本無法接收跳轉時傳送的新資料!
  • 以下,通過一個樣例來具體解釋:
  • 以上代碼中的

    CourseDetailActivity

    在配置檔案裡設定了啟動模式是

    SingleTop

    模式,依據上面啟動模式的介紹可得知,當

    CourseDetailActivity

    處于棧頂時。
  • 再次跳轉頁面到

    CourseDetailActivity

    時會直接複用原有的

    Activity

    ,并且此頁面須要展示的資料是從

    getIntent()

    方法得來,可是

    initData()

    方法不會再次被調用,此時頁面就無法顯示新的資料。
  • 當然這樣的情況系統早就為我們想過了,這時我們須要另外一個回調

    onNewIntent(Intent intent)

    方法。此方法會傳入最新的

    intent

    ,這樣我們就能夠解決上述問題。這裡建議的方法是又一次去

    setIntent

    。然後又一次去初始化資料和

    UI

    。代碼例如以下所看到的:
  • 這樣,在一個頁面中能夠反複跳轉并顯示不同的内容。

2.4 快速啟動一個 Activity

  • 這個問題其實也是比較簡單的,就是不要在

    Activity

    onCreate

    方法中執行過多繁重的操作,并且在

    onPasue

    方法中同樣不能做過多的耗時操作。

2.5 啟動流程

2.6 Activity 的 Flags

  • 标記位既能夠設定Activity的啟動模式,如同上面介紹的,在動态指定啟動模式,比方

    FLAG_ACTIVITY_NEW_TASK

    FLAG_ACTIVITY_SINGLE_TOP

    等。它還能夠影響

    Activity

    的運作狀态 ,比方

    FLAG_ACTIVITY_CLEAN_TOP

    FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

    等。
  • 以下介紹幾個基本的标記位,切勿死記,了解幾個就可以,須要時再查官方文檔。
  • FLAG_ACTIVITY_NEW_TASK

  1. 作用是為

    Activity

    “SingleTask”

    啟動模式。跟在

    AndroidMainfest.xml

    指定效果同樣
  • FLAG_ACTIVITY_SINGLE_TOP

  1. Activity

    “SingleTop”

    啟動模式,跟在

    AndroidMainfest.xml

    指定效果同樣。
  • FLAG_ACTIVITY_CLEAN_TOP

  1. 具有此标記位的

    Activity

    ,啟動時會将與該

    Activity

    在同一任務棧的其他

    Activity

    出棧。
  2. 一般與

    SingleTask

    啟動模式一起出現。
  3. 它會完畢

    SingleTask

    的作用。
  4. 但事實上

    SingleTask

    啟動模式預設具有此标記位的作用
  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

  1. Activity

    不會出如今曆史

    Activity

    的清單中
  2. 使用場景:當某些情況下我們不希望使用者通過曆史清單回到

    Activity

    時,此标記位便展現了它的效果。
  3. 它等同于在

    xml

    Activity

    的屬性.

2.7 onNewInstent()方法什麼時候執行

這個是啟動模式中的了,當此

Activity

的執行個體已經存在,并且此時的啟動模式為

SingleTask

SingleInstance

,另外當這個執行個體位于棧頂且啟動模式為

SingleTop

時也會觸發

onNewInstent()

三、 資料

3.1 Activity 間通過 Intent 傳遞資料大小限制

  • Intent

    在傳遞資料時是有大小限制的,這裡官方并未詳細說明,不過通過實驗的方法可以測出資料應該被限制在

    1MB

    之内(

    1024KB

  • 我們采用傳遞

    Bitmap

    的方法,發現當圖檔大小超過

    1024

    (準确地說是

    1020

    左右)的時候,程式就會出現閃退、停止運作等異常(不同的手機反應不同)
  • 是以可以判斷

    Intent

    的傳輸容量在

    1MB

    之内。

3.2 記憶體不足時系統會殺掉背景的Activity,若需要進行一些臨時狀态的儲存,在哪個方法進行

  • Activity

    onSaveInstanceState()

    onRestoreInstanceState()

    并不是生命周期方法,它們不同于

    onCreate()

    onPause()

    等生命周期方法,它們并不一定會被觸發。
  • onSaveInstanceState()

    方法,當應用遇到意外情況(如:記憶體不足、使用者直接按

    Home

    鍵)由系統銷毀一個

    Activity

    onSaveInstanceState()

    會被調用。
  • 但是當使用者主動去銷毀一個

    Activity

    時,例如在應用中按傳回鍵,

    onSaveInstanceState()

    就不會被調用。
  • 除非該

    activity

    不是被使用者主動銷毀的,通常

    onSaveInstanceState()

    隻适合用于儲存一些臨時性的狀态,而

    onPause()

    适合用于資料的持久化儲存。

3.3 onSaveInstanceState() 被執行的場景

  • 系統不知道你按下

    HOME

    後要運作多少其他的程式,自然也不知道

    activity A

    是否會被銷毀
  • 是以系統都會調用

    onSaveInstanceState()

    ,讓使用者有機會儲存某些非永久性的資料。以下幾種情況的分析都遵循該原則:
  1. 當使用者按下

    HOME

    鍵時
  2. 長按

    HOME

    鍵,選擇運作其他的程式時
  3. 鎖屏時
  4. activity A

    中啟動一個新的

    activity

  5. 螢幕方向切換時

3.4 兩個 Activity 之間跳轉時必然會執行的方法

一般情況下比如說有兩個

activity

, 分别叫

A

,

B

,當在

A

裡面激活

B

元件的時候,

A

會調用

onPause()

方法,然後

B

調用

onCreate()

onStart()

onResume()

這個時候

B

覆寫了窗體,

A

onStop()

方法. 如果

B

是個透明的,或者 是對話框的樣式, 就不會調用

A

onStop()

3.5 用 Intent 去啟動一個Activity 之外的方法

  • 使用

    adb shell am

    指令
  1. am

    啟動一個

    activity

  2. adb shell am start com.example.fuchenxuan/.MainActivity

  3. am

    發送一個廣播,使用

    action

  4. adb shell am broadcast -a magcomm.action.TOUCH_LETTER

3.6 scheme 跳轉協定

3.6.1 定義

  • 伺服器可以定制化跳轉

    app

    頁面
  • app

    可以通過

    Scheme

    跳轉到另一個

    app

  • h5

    頁面跳轉

    app

    原生頁面

3.6.2 協定格式:

  • qh

    代表

    Scheme

    協定名稱
  • test

    Scheme

    作用的位址域
  • 8080

    代表改路徑的端口号
  • /goods

    代表的是指定頁面(路徑)
  • goodsId

    name

    代表傳遞的兩個參數

3.6.3 Scheme使用

  • 定義一個

    Scheme

  • 擷取

    Scheme

    跳轉的參數
  • 調用方式
  1. 原生調用
  1. html調用
  1. 判斷某個Scheme是否有效
  • 關于scheme跳轉協定,可以檢視下面的部落格,站在巨人的肩膀上,才能看得更遠
    [Android産品研發(十一)-->應用内跳轉Scheme協定](https://links.jianshu.com/go?to=http%3A%2F%2Fblog.csdn.net%2Fqq_23547831%2Farticle%2Fdetails%2F51685310)
               

四、 Context

4.1 Context , Activity , Appliction 的差別

  • 相同:

    Activity

    Application

    都是

    Context

    的子類。
  • Context

    從字面上了解就是上下文的意思, 在實際應用中它也确實是起到了管理 上下文環境中各個參數和變量的總用, 友善我們可以簡單的通路到各種資源。
  • 不同:維護的生命周期不同。

    Context

    維護的是目前的

    Activity

    的生命周期,

    Application

    維護的是整個項目的生命周期。
  • context

    的時候, 小心記憶體洩露, 防止記憶體洩露

4.2 Context 是什麼

  • 它描述的是一個應用程式環境的資訊,即上下文。
  • 該類是一個抽象(

    abstract class

    )類,

    Android

    提供了該抽象類的具體實 現類(

    ContextIml

    )。
  • 通過它我們可以擷取應用程式的資源和類, 也包括一些應用級别操作, 例如:啟動一個

    Activity

    ,發送廣播,接受

    Intent

    ,資訊,等。

4.2.1 附加一張 Context 繼承關系圖

4.3 擷取目前螢幕 Activity 的對象

  • 使用 ActivityLifecycleCallbacks
    [Android 如何擷取目前Activity執行個體對象?](https://links.jianshu.com/go?to=http%3A%2F%2Fblog.csdn.net%2Fvfush%2Farticle%2Fdetails%2F51483436)
               

4.4 Activity 的管理機制

  1. 什麼是 ActivityRecord
  2. 什麼是 TaskRecord
  3. 什麼是 ActivityManagerService

4.5 什麼是 Activity

  • 四大元件之一,通常一個使用者互動界面對應一個

    activity

  • activity

    Context

    的子類,同時實作了

    window.callback

    keyevent.callback

    ,可以處理與窗體使用者互動的事件。
  • 開發中常用的有

    FragmentActivity

    ListActivity

    TabActivity

    Android 4.0

    Fragment

    取代)

五、 程序

5.1 Android 程序優先級

  • 前台 / 可見 / 服務 / 背景 / 空

5.1.1 前台程序:Foreground process

  • 使用者正在互動的

    Activity

    onResume()

  • 當某個

    Service

    綁定正在互動的

    Activity

  • 被主動調用為前台

    Service

    startForeground()

  • 元件正在執行生命周期的回調(

    onCreate()

    onStart()

    onDestory()

  • BroadcastReceiver

    正在執行

    onReceive()

5.1.2 可見程序:Visible process

  • 我們的

    Activity

    處在

    onPause()

    (沒有進入

    onStop()

  • 綁定到前台

    Activity

    Service

5.1.3 服務程序:Service process

  • 簡單的

    startService()

    啟動。

5.1.4 背景程序:Background process

  • 對使用者沒有直接影響的程序 ---

    Activity

    處于

    onStop()

    的時候。
  • android:process=":xxx"

5.1.5 空程序:Empty process

  • 不含有任何的活動的元件。(

    Android

    設計的,處于緩存的目的,為了第二次啟動更快,采取的一個權衡)

5.2 可見程序

可見程序指部分程式界面能夠被使用者看見,卻不在前台與使用者互動的程序。例如,我們在一個界面上彈出一個對話框(該對話框是一個新的

Activity

),那麼在對話框後面的原界面是可見的,但是并沒有與使用者進行互動,那麼原界面就是可見程序。
  • 一個程序滿足下面任何一個條件都被認為是可視的:
  1. 寄宿着一個不是前台的活動,但是它對使用者仍可見(它的

    onPause()

    方法已經被調用)。舉例來說,這可能發生在,如果一個前台活動在一個對話框(其他程序的)運作之後仍然是可視的,比如輸入法的彈出時。
  2. 寄宿着一個服務,該服務綁定到一個可視的活動。
  • 一個可視程序被認為是及其重要的且不會被殺死,除非為了保持前台程序運作。

5.3 服務程序

  • 服務程序是通過

    startService()

    方法啟動的程序,但不屬于前台程序和可見程序。例如,在背景播放音樂或者在背景下載下傳就是服務程序。
  • 系統保持它們運作,除非沒有足夠記憶體來保證所有的前台程序和可視程序。

5.4 背景程序

  • 背景程序是一個保持着一個目前對使用者不可視的活動(已經調用

    Activity

    對象的

    onStop()

    方法)(如果還有除了

    UI

    線程外其他線程在運作話,不受影響)。
例如我正在使用

qq

和别人聊天,這個時候

qq

是前台程序,但是當我點選

Home

鍵讓

qq

界面消失的時候,這個時候它就轉換成了背景程序。
  • 這些程序沒有直接影響使用者體驗,并且可以在任何時候被殺以收回記憶體用于一個前台、可視、服務程序。
  • 一般地有很多背景程序運作着,是以它們保持在一個

    LRU

    least recently used

    ,即最近最少使用,如果您學過作業系統的話會覺得它很熟悉,跟記憶體的頁面置換算法

    LRU

    一樣)清單以確定最近使用最多的活動的程序最後被殺。

5.5 空程序

  • 空程序是一個沒有保持活躍的應用程式元件的程序,不包含任何活躍元件。
  • 保持這個程序可用的唯一原因是作為一個

    cache

    以提高下次啟動元件的速度。系統程序殺死這些程序,以在程序

    cache

    和潛在的核心

    cache

    之間平衡整個系統資源。
  • android

    程序的回收順序從先到後分别是:空程序,背景程序,服務程序,可見程序,前台程序。

5.6 什麼是 ANR,如何避免

5.6.1 什麼是ANR

  • ANR

    ,全稱為

    Application Not Responding

  • Android

    中,如果你的應用程式有一段時間沒有響應,系統會向使用者顯示一個對話框,這個對話框稱作應用程式無響應對話框。

5.6.2 使用者行為

  • 使用者可以選擇讓程式繼續運作,也可以讓程式停止運作。
  • 他們在使用你的應用程式時,并不希望每次都要處理這個對話框。
  • 是以,在程式裡對響應性能的設計很重要,這樣,系統不會顯示

    ANR

    給使用者。

5.6.3 Android不同元件ANR逾時時間不同

  • 不同的元件發生

    ANR

    的時間不一樣,主線程(

    Activity

    Service

    )是

    5

    秒,

    BroadCastReceiver

    10

    秒。

5.6.4 解決方案

  1. 将所有耗時操作,比如通路網絡,

    Socket

    通信,查詢大量

    SQL

    語句,複雜邏輯計算等都放在子線程中去,然後通過

    handler.sendMessage

    runonUITread

    AsyncTask

    等方式更新

    UI

    ,以確定使用者界面操作的流暢度。
  2. 如果耗時操作需要讓使用者等待,那麼可以在界面上顯示進度條。

5.7 android的任務棧 Task

  • Task

    包含的就是

    activity

    集合,

    android

    系統可以通過任務棧有序的管理

    activity

  • 一個app當中可能不止一個任務棧,在某些情況下,一個

    activity

    也可以獨享一個任務棧(

    singleInstance

    模式啟動的

    activity

總結

  1. 本文基本涵蓋了

    Android Activity

    的所有知識點。對于

    App

    啟動、

    AMS

    希望大家能根據文中連結或者

    Google

    搜尋的形式繼續展開學習。
  2. 重點

    :關于

    Android

    的四大元件,到現在為止我才總結完 Activity ,馬上我将繼續針對,

    Service

    BroadcastRecevier

    等,以及事件分發、滑動沖突、新能優化等重要子產品,進行全面總結,歡迎大家關注 _yuanhao 的 簡書 ,友善及時接收更新

推薦閱讀:

2019年鴻洋大神最新整理一線網際網路公司Android中進階面試題總結(附答案解析) 臨近畢業,2020春招困惑你的十大問題,你中招了嗎? Android社招最全面試題