天天看點

android service中更新ui_1-2Android基礎知識-ServiceService 定義Service 生命周期Service 的優先級JobScheduleServiceBroadcastReceiver發送和接收流程本地廣播 & 普通廣播ContentProvider通路 ContentProvider

這次把安卓剩餘的三個元件Service、BroadcastReceiver、ContentProvider放在一起,也是因為,剩餘三個元件的複雜程度、使用頻率不及Activity。

不說話,先看圖

android service中更新ui_1-2Android基礎知識-ServiceService 定義Service 生命周期Service 的優先級JobScheduleServiceBroadcastReceiver發送和接收流程本地廣播 & 普通廣播ContentProvider通路 ContentProvider
android service中更新ui_1-2Android基礎知識-ServiceService 定義Service 生命周期Service 的優先級JobScheduleServiceBroadcastReceiver發送和接收流程本地廣播 & 普通廣播ContentProvider通路 ContentProvider

Service 定義

Service 是可以在背景長期執行而沒有使用者互動的基礎元件。Service 運作在主線程,不可以做耗時的操作。Thread 泛指建立的子線程,不能更新 UI。

Service 生命周期

Service 的生命周期,預期方式關聯。啟動方式有主動啟動、綁定啟動兩種。看下兩種啟動方式的流程圖

android service中更新ui_1-2Android基礎知識-ServiceService 定義Service 生命周期Service 的優先級JobScheduleServiceBroadcastReceiver發送和接收流程本地廣播 & 普通廣播ContentProvider通路 ContentProvider

Service 流程中的核心的方法如下

  • onCreate
  • onStartCommand
  • onBind
  • onDestory

Service 的優先級

Service 按照使用場景,可以區分foreground、background、bind 三種類型,不同類型的優先級不同。優先級越低,在系統資源緊張時,越容易被系統回收掉。

優先級順序:foreground > bind > background

在 androidmanifest 中,也可以配置 service 的優先級 android:priority = "xxxx",xxxx可以配置為整數,數字越大,優先級越高,最高值為 1000。

JobScheduleService

JobIntentService 是 Android 8.0 新增的 Service 子類,替代 IntentService。8.0 系統以後,禁止在背景直接建立 Service,但可以建立 JobIntentService。官方的定義如下:

Helper for processing work that has been enqueued for a job/service. When running on Android O or later, the work will be dispatched as a job via JobScheduler.enqueue. When running on older versions of the platform, it will use Context.startService.
           

解釋:JobIntentService 用于處理被加入到隊列的 job/service 任務的一個輔助工具。當運作在 Android O 或更高版本時,任務将作為 job 通過 JobScheduler.enqueue() 進行分發;當運作在較老版本的平台上時,任務仍舊會使用 Context.startService() 執行

Android 8.0 及以上版本 JobIntentService 和 JobService 做的事情是相同的,都是等着 JobScheduler 配置設定任務來執行。

不同點在于,JobService 使用的 handler 使用的是主線程的 Looper,是以需要在 onStartJob() 方法中手動建立 AsyncTask 去執行耗時任務,而 JobIntentService 則幫我們處理這一過程,使用它隻需要寫需要做的任務邏輯即可,不用擔心阻塞主線程的問題。另外,向 JobScheduler 傳遞任務操作也更簡單了,不需要在指定 JobInfo 中的參數,直接 enqueueWork() 方法就可以了。這有點像 Service 和 IntentService 的關系。

BroadcastReceiver

廣播的定義很好了解,有發送方,有接收方,可以用于在不同的 App ,同一個 App 不同的元件、程序間通信。按發送方,廣播可以分為以下四種類型

  • 普通廣播
  • 有序廣播
  • 本地廣播
  • 系統廣播

按照注冊方式,又可以區分為兩種

  • 靜态注冊
  • 動态注冊

發送和接收流程

  1. 廣播接收者(BroadcastReceiver)通過 Binder 機制,向 AMS 注冊成為廣播接收者。
  2. 廣播的發送者,通過 Binder 機制,向 AMS 發送廣播。
  3. AMS查找符合條件(IntentFilter、Permission)的 BroadcastReceiver,将廣播發送到相應的Receiver 的隊列中
  4. 消息循環執行拿到此廣播,回調 BroadcastReceiver 的 onReceiver 方法

本地廣播 & 普通廣播

相比普通廣播,本地廣播更加安全、高效。本地廣播的發送,隻在 App 自身内傳播,不必擔心隐私洩露的問題,其他 App 也無法發送該廣播,故不用擔心安全漏洞。本地廣播内部通過 Handler 實作,不牽涉跨程序通信,效率更高。

ContentProvider

ContentProvider 是一個内容提供者,一般用于 App 間資料互動和共享。底層依然使用的 Binder 機制通信。

android service中更新ui_1-2Android基礎知識-ServiceService 定義Service 生命周期Service 的優先級JobScheduleServiceBroadcastReceiver發送和接收流程本地廣播 & 普通廣播ContentProvider通路 ContentProvider

通路 ContentProvider

通路 ContentProvider 的流程大緻如下

android service中更新ui_1-2Android基礎知識-ServiceService 定義Service 生命周期Service 的優先級JobScheduleServiceBroadcastReceiver發送和接收流程本地廣播 & 普通廣播ContentProvider通路 ContentProvider

看下面的示例代碼

// Queries the user dictionary and returns resultscursor = getContentResolver().query(    UserDictionary.Words.CONTENT_URI,   // The content URI of the words table    projection,                        // The columns to return for each row    selectionClause,                   // Selection criteria    selectionArgs,                     // Selection criteria    sortOrder);                        // The sort order for the returned rows        
           

query 方法的參數,對比 SQL 文法,可以看下差異

query() argumentSELECTNotesUriFROM table_nameUri maps to the table in the provider named table_nameprojectioncol,col,colProjection is an array of columnsselectionWHERE col = valueSelection specifies the criteria for selection rowsselectionArgssortOrderORDER by col,colsortOrder specifies the order in which rows appear in the returned Cursor

可以了解為,ContentProvider 提供了一套更加友善、豐富的通路資料的方法,可以做到讀寫分離,更加安全可靠。

#android#

#service#

#2020#