要點提煉|開發藝術之四大組件

提到四大組件你們確定再熟悉不過了,本篇側重於對四大組件工做過程進行分析:

  • 概述
  • 工做過程
    • Activity
    • Service
    • BroadcastReceiver
    • ContentProvider

1.概述html

a.Activityandroid

  • 類型:展現型組件。
  • 做用:展現一個界面並和用戶交互。
  • 使用:
    • 須要在AndroidManifest中註冊。
    • 須要藉助Intent啓動,兩種方式:
      • 顯示Intent: Intent intent=new Intent(xxx.this,xxx.class); startActivity(intent);
      • 隱式Intent: Intent intent=new Intent(); intent.setAction(xxx); intent.addCategory(xxx); startActivity(intent);
    • 四種啓動模式:
      • standard:標準模式
      • singleTop:棧頂複用模式
      • singleTask:棧內複用模式
      • singleInstance:單實例模式
    • 對用戶而言是可見的。
    • 經過finish()結束一個Activity。

相關基礎入門之Activity篇開發藝術之Activityide

b.Service源碼分析

  • 類型:計算型組件。
  • 做用:在後臺執行一系列計算任務,耗時的後臺計算建議在單獨的線程中執行。
  • 使用:
    • 須要在AndroidManifest中註冊。
    • 須要藉助Intent啓動: Intent intent = new Intent(xxx.this, xxx.class); startService(intent);
    • 兩種運行狀態:
      • 啓動狀態:經過startService()
      • 綁定狀態:經過bindService()
    • 用戶沒法感知。
    • 經過unBindService()stopService()徹底中止一個Service。

相關基礎入門之Service篇post

c.BroadcastReceiverthis

  • 類型:消息型組件。
  • 做用:在不一樣的組件乃至不一樣的應用之間傳遞消息。
  • 使用:
    • 兩種註冊方式:
      • 動態註冊:經過Context.registerReceiver()& Context.unRegisterReceiver(),必需要應用啓動才能註冊並接收廣播。
      • 靜態註冊:在AndroidManifest文件中註冊,不須要啓動應用便可接收廣播。
    • 須要藉助Intent發送廣播: Intent intent = new Intent("xxx"); sendBroadcast(intent);
    • 四種廣播類型:
      • 普通廣播
      • 有序廣播
      • 本地廣播
      • 粘性廣播
    • 用戶沒法感知。
    • 沒有中止概念。

相關基礎入門之BroadcastReceiver篇spa

d.ContentProvider.net

  • 類型:共享型組件。
  • 做用:向其餘組件乃至其餘應用共享數據。
  • 使用:
    • 須要在AndroidManifest中註冊。
    • 無需藉助Intent啓動。
    • 四種操做:注意須要處理好線程同步
      • insert():添加數據
      • update():更新數據
      • delete():刪除數據
      • query():查詢數據
    • 用戶沒法感知。
    • 無需手動中止。

相關基礎入門之ContentProvider篇IPC方式之ContentProvider線程

考考本身android四大組件的運行狀態3d


二.工做過程

因爲相關源碼很是多,這裏借用@amurocrash的UML圖來提煉流程更爲直觀,另附相關源碼分析的文章供你們詳細瞭解。

a.Activity

Activity啓動過程流程圖:

Activity啓動過程

結論

  • ActivityManagerService、ApplicationThread都是Binder
  • Application的建立也是經過Instrumentation來完成的,這個過程和Activity對象同樣,都是經過類加載器來實現的。
  • Activity的啓動過程最終回到ApplicationThread中,經過ApplicationThread.scheduleLaunchActivity() 將啓動Activity的消息發送並交由Handler H處理。
  • Handler H對消息的處理會調用handleLaunchActivity()->performLaunchActivity()得以最終完成Activity的建立和啓動。

源碼分析Activity的工做過程

b.Service

  • Service啓動過程流程圖:

Service啓動過程

  • Service綁定過程流程圖:

Service綁定過程

結論

  • ContextImpl是Context的具體實現,經過Activity.attach()和Activity創建關聯。Activity.attach()中還會完成Window的建立並和Activity&Window的關聯,由此事件可傳遞給Window。
  • ActivityServices是一個輔助ActivityManagerService(AMS)進行Service管理的類,包括Service的啓動、綁定和中止。
  • 和Activity相似的,Service的啓動/綁定過程最終回到ApplicationThread中,經過ActivityThread.handleCreateService()/ActivityThread.handleBindService完成Service的啓動/綁定,注意綁定Service的後續還必須 告知客戶端已經成功鏈接Service 的這一流程,由ActivityManagerService.publishService()去完成。

源碼分析Service的工做過程

c.ContentProvider

  • ContentProvider啓動過程流程圖:

ContentProvider啓動過程

  • 啓動的入口爲ActivityThread.main():建立ActivityThread實例並建立主線程消息隊列;
  • ->ActivityThread.attach():遠程調用AMS.attachApplication()並提供ApplicationThread用於和AMS的通訊;
  • ->AMS.attachApplication():經過ActivityThread.bindApplication()方法和Handler H來調回ActivityThread.handleBindApplication();
  • ->ActivityThread.handleBindApplication():先建立Application、再加載ContentProvider、最後回調Application.onCreate()

圖片來源四大組件的工做過程

  • Query過程流程圖:

Query過程

insert()delete()update()相似,這裏不展開

結論

  • ContentProvider的multiprocess屬性:ContentProvider是不是單例,通常用單例。
  • 訪問ContentProvider須要ContentResolver,其真正實現類是ApplicationContentResolver。當ContentProvider所在進程未啓動時,第一次訪問它會觸發ContentProvider的建立以及進程啓動。
  • 當ContentProvider所在的進程啓動時,會同時被啓動並被髮布到AMS中。注意:ContentProvider.onCreate()Application.onCreate()執行。
  • 一樣的,最終經過ActivityThread.handleBindApplication()完成ContentProvider的建立。

源碼分析 ContentProvider的工做過程

d.BroadcastReceiver

  • 四大組件的靜態註冊都是在應用安裝時由PackageManagerService(PMS)解析註冊,當動態註冊Service時流程爲:

Receiver動態註冊過程

  • 廣播發送和接收過程流程圖:

廣播發送和接收過程

結論:

  • 動態註冊廣播最終會跨進程交給AMS,並把遠程Receiver( 實際上傳的是IIntentReceiver,是個Binder )對象和遠程IntentFilter保存起來,完成註冊任務。
  • 發送廣播時,系統未intent添加了兩個標記位:
    • FLAG_INCLUDE_STOPPED_PACKAGES :廣播也會發送到已經中止的APP(兩個標記共存時,以該標記爲準)
    • FLAG_EXCLUDE_STOPPED_PACKAGES :廣播不會發送給已經中止的APP(系統爲全部廣播默認添加該標記)
  • 最終在ReceiverDispatcher .performReceive ()裏回調了Receiver 的onReceive(),使得廣播得以接收並處理。

源碼分析BroadcastReceiver 的工做過程


但願這篇文章對你有幫助~

相關文章
相關標籤/搜索