Android 初級面試者拾遺(前臺界面篇)之 Activity 和 Fragment

Context

Android 系統組件不一樣於普通類對象,可以直接建立實例,須要各自的上下文環境——Context。
Context 上下文環境確保 Android 系統組件(Activity、Service、BroadcastReceiver)可以正常工做。java

Context 大體分爲三種類型(一般能夠通用):android

  • Application
  • Activity
  • Service

getApplication() = getApplicationContext() = Application
getApplicationContext() 方法的做用域更廣,任何一個 Context 實例(Activity, Service)經過調用 getApplicationContext() 方法均可以獲取到 Application。app

context

  • ContextWrapper 抽象接口類
  • ContextImpl 具體實現類

ContextWrapper 中的方法經過組合委託方式交由 ContextImpl 具體實現。
getBaseContext() = ContextImplide

Context 數量計算公式:
Context 數量 = Activity 數量 + Service 數量 + 1(Application)oop

Activity

Activity 返回棧

Android 使用任務(Task)返回棧(Back Stack)管理 Activity,任務是一組存放在棧(後進先出)裏的 Activity 集合。佈局

返回棧管理 Activity 的入棧出棧操做,例如:啓動新的 Activity 執行入棧操做;Back 鍵返回或調用 finish() 方法,銷燬 Activity 執行出棧操做。spa

系統老是顯示處於棧頂的 Activity。線程

任務(Task)從前臺移至後臺時,返回棧中全部的 Activity 都會進入中止狀態,可是各個 Activity 在棧中的順序都會原封不動保留。code

Activity 四種狀態

  • 運行狀態
  • 暫停狀態
  • 中止狀態
  • 銷燬狀態

運行狀態xml

Activity 處於返回棧的棧頂位置,正在運行與用戶發生着交互,系統不肯回收此種狀態的 Activity。

暫停狀態

Activity 再也不處於返回棧的棧頂位置,可是依然可見,並不是每一個 Activity 都會佔滿屏幕,例如對話框形式的 Activity 只是佔據部分區域,其後面的 Activity 是可見的。系統一樣不肯回收此種狀態的 Activity,除非在內存嚴重不足的狀況下,才考慮回收此種狀態的 Activity。

中止狀態

Activity 再也不處於返回棧的棧頂位置,而且徹底處於不可見狀態,系統仍然會保存中止狀態的 Activity 的成員變量,但並不可靠,當其餘地方須要內存時,系統可能回收此種狀態的 Activity,保證內存充足。

銷燬狀態

Activity 從返回棧出棧變爲銷燬狀態,系統樂於回收此種狀態的 Activity,保證內存充足。

Activity 生命週期回調方法

  • onCreate()
  • onStart()
  • onResume()
  • onPause()
  • onStop()
  • onDestroy()
  • onRestart()

onCreate() 方法在 Activity 第一次被建立的時候調用,完成 Activity 初始化操做,例如加載佈局、綁定事件...。
onStart() 方法在 Activity 由不可見變爲可見的時候調用。
onResume() 方法在 Activity 準備好與用戶進行交互的時候調用。
onPause() 方法在系統準備啓動或者恢復另外一個 Activity 的時候調用。
onStop() 方法在 Activity 由可見變爲不可見的時候調用。
onDestroy() 方法在 Activity 銷燬以前調用。
onRestart() 方法在 Activity 由中止狀態變爲運行狀態的時候調用。

activity_lifecycle

onPause() ——> onResume() 暫停狀態向運行狀態切換。對話框式 Activity 沒法佔滿屏幕,其後面的 Activity 依然可見。

Activity 回收狀況

Activity 執行 onStop() 方法,處於中止狀態(不可見),可能被系統回收。
若系統內存充足,保留 Activity 狀態數據,當用戶再次返回 Activity,執行 onRestart() 方法。
若系統內存不足,將 Activity 回收,用戶再次返回 Activity,執行 onCreate() 而非 onRestart()。

Activity 提供 onSaveInstanceState() 回調方法,保證在 Activity 被回收以前調用此方法,保存臨時數據。隨後能夠在 Activity onCreate(Bundle savedInstanceState) 方法恢復數據。

  • 完整生存期:onCreate() ——> onDestroy()
  • 可見生存期:onStart() ——> onStop()
  • 前臺生存期:onResume() ——> onPause()

Activity 啓動模式

定義啓動模式

  1. 使用 AndroidManifest.xml 文件指定 <activity> 標籤的 android:launchMode 屬性。
  2. 調用 startActivity() 方法時使用 Intent FLAG 參數。
    Intent 中定義的啓動模式 FLAG 將會覆蓋 AndroidManifest.xml 文件中的定義。
  • standard
  • singleTop
  • singleTask
  • singleInstance

standard 模式不在意一個 Activity 是否已經存在於返回棧之中,每次啓動都會建立新的 Activity 放入返回棧中。

standard

singleTop 模式啓動 Activity 時,若是當前返回棧的棧頂位置已經是該類型 Activity,則無需建立新的實例,直接使用棧頂位置的 Activity。若是該類型 Activity 存在於返回棧中,但並不是處於棧頂位置,仍是會建立新的 Activity 實例。

singleTop

singleTask 模式啓動 Activity 時,若是當前返回棧中存在該類型 Activity,則直接使用該 Activity 實例,並將這個 Activity 實例之上的 Activity 通通出棧。若是整個返回棧中不存在該類型 Activity,仍是會建立新的 Activity 實例。

singleTask

singleTop 和 singleTask 都是爲了解決重複建立 Activity 問題,singleTop 的做用域是棧頂,singleTask 的做用域是整個返回棧。

singleInstance 建立活動到獨立返回棧,從而實現不一樣程序能夠共享 Activity 實例。

singleInstance

taskAffinity 參數用於指定 Activity 依附於哪一個任務。

Activity 啓動流程

ActivityManagerService,負責系統中全部的 Activity 的生命週期。
ActivityThread,App 真正的入口,執行 main() 方法,初始化主線程的消息循環隊列。
Zygote,Linux 系統全部進程均是由 「init「 進程拷貝(fork)而來。

點擊應用圖標 Launcher 程序將點擊事件轉換爲 startActivity(intent),經過 Binder IPC 路由通知 ActivityManagerService。ActivityManagerService 首先經過 PackageManager 收集 intent 信息,而後檢查是否具備喚醒組件的權限,開啓新的 TASK(FLAG_ACTIVITY_NEW_TASK),最後建立進程去實例化組件。

建立進程過程:
ActivityManagerService Process.start() 由 Zygote 進程(Linux init 進程)孵化出應用進程,並實例化 ActivityThread(主線程/UI 線程)對象執行 main() 方法,初始化主線程的 Looper、Handler,開啓消息循環隊列,無限等待消息到來(Looper.loop())。

綁定應用過程:
bindApplication() 方法發送 BIND_APPLICATION 消息到消息循環隊列,關聯(attach)建立的進程和應用程序。加載應用程序 Class 到線程私有內存空間。

啓動 Activity 過程:
realStartActivity() 發送 LAUNCH_ACTIVITY 消息到消息循環隊列,啓動 Activity 管理自身生命週期,首先回調 onCreate() 方法。

Activity 啓動流程

scheme 頁面跳轉協議

自定義 scheme 協議以便跳轉至 App 指望到達的各個頁面,可由服務端定製化。

  • 原生 App 頁面
  • HTML5 頁面
  • 其餘 App 頁面

Fragment

Fragment 是一種能夠嵌入在 Activity 中的 UI 片斷,就好像是 mini Activity 一樣包含佈局,並擁有本身的生命週期。Android 引入 Fragment 概念,力求在開發過程當中同時兼顧手機和平板屏幕的大小。

fragment1

fragment2

Fragment 結合 Activity 使用方式

靜態建立方式和動態建立方式

  • 在佈局中靜態添加 <fragment> 標籤,經過 android:name 屬性指定 Fragment 類名。
  • 在程序運行時動態地添加 Fragment 到 Activity 中。

動態添加過程:

  1. 建立 Fragment 實例
  2. 獲取 FragmentManager,在 Activity 中經過 getSupportFragmentManager() 方法能夠獲得。
  3. FragmentManager 開啓事務 FragmentTransaction
  4. FragmentTransaction 向佈局中的指定容器(ViewGroup)添加或替換(replace) Fragment
  5. 提交事務 FragmentTransaction.commit()

FragmentTransaction add()、replace() 方法區別

不一樣之處在於,是否清空容器後再添加 Fragment,replace() 會清空而 add() 不會。一般 add() 方法須要配合 hide()remove() 方法一塊兒使用,而 replace() 方法通常單獨使用。

transaction.replace(viewId, fragment);

等價操做:

transaction.add(viewId, fragment);
transaction.show(fragment);
transaction.hide(preFragment);
transaction.remove(preFragment);

Fragment 通訊方式

Activity 調用 Fragment 方法:Activity FragmentManager findFragmentById() 方法獲取 Fragment 實例。

Fragment 調用 Activity 方法:Fragment getActivity() 方法獲取 Activity 實例。

Fragment 調用 Fragment 方法:Activity 做爲中介。

Fragment 返回棧

FragmentTransaction 提供 addToBackStack() 方法,能夠添加事務到返回棧中。根據應用需求決定是否使用 addToBackStack() 方法。例如 Back 鍵返回時顯示上一次 FragmentTransaction 記錄結果,則需事先調用 addToBackStack() 方法。

addToBackStack() 方法保存的是一系列針對 FragmentTransaction 的操做記錄。

Fragment 四種狀態

  • 運行狀態
  • 暫停狀態
  • 中止狀態
  • 銷燬狀態

運行狀態:Fragment 所關聯的 Activity 處於運行狀態

暫停狀態:Fragment 所關聯的 Activity 處於暫停狀態

中止動態:當 Activity 進入中止狀態時,與它相關聯的 Fragment 就會進入中止狀態。或者經過調用 FragmentTransaction 的 remove()replace() 方法將 Fragment 從 Activity 中移除,但在事務提交以前調用 addToBackStack() 方法,這時 Fragment 也會進入中止狀態。

銷燬狀態:Fragment 依附於 Activity 而存在,所以 Activity 銷燬,與它相關聯的 Fragment 就會進入銷燬狀態。或者經過調用 FragmentTransaction 的 remove()replace() 方法將 Fragment 從 Activity 中移除,但在事務提交以前沒有調用 addToBackStack() 方法,這時 Fragment 也會進入銷燬狀態。

Fragment 生命週期回調方法

  • onAttach()
  • onCreate()
  • onCreateView()
  • onActivityCreated()
  • onStart()
  • onResume()
  • onPause()
  • onStop()
  • onDestroyView()
  • onDestroy()
  • onDetach()
  • onRestart()

除了與 Activity 相同的生命週期回調方法以外,Fragment 還附加幾個回調方法。

onAttach():當 Fragment 和 Activity 創建關聯的時候調用
onCreateView():爲 Fragment 建立視圖(加載佈局)的時候調用
onActivityCreated():確保 Fragment 和關聯的 Activity 都建立完畢
onDestroyView():當 Fragment 移除視圖結構的時候調用
onDetach():當 Fragment 和 Activity 解除關聯的時候調用

activity_fragment_lifecycle

與 Activity 生命週期協調一致

Fragment 與 ViewPager 組合使用

ViewPager extends ViewGroup,容許用戶左右滑動(幻燈片效果)瀏覽視圖,並根據提供的 PagerAdapter 填充數據。

FragmentPagerAdapter 與 FragmentStatePagerAdapter 的區別

ViewPager 提供兩種頁面適配器(PagerAdapter)來管理不一樣的 Fragment 之間滑動切換。

FragmentPagerAdapter:ViewPager 中的全部 Fragment 實例常駐內存,當 Fragment 變得不可見時僅銷燬視圖結構,即調用 onDestroyView() 方法。因爲 FragmentPagerAdapter 內存消耗較大,因此適合少許靜態頁面的場景。

FragmentStatePagerAdapter:當 Fragment 變得不可見時,不只銷燬視圖層次,Fragment 實例也被銷燬,即調用了 onDestroyView()onDestroy() 方法,僅保存 Fragment 狀態。相比而言, FragmentStatePagerAdapter 內存佔用較小,因此適合大量動態頁面的場景。

相關文章
相關標籤/搜索