国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

[譯] WorkManager 基礎(chǔ)入門

番茄西紅柿 / 1551人閱讀

摘要:讓我們探討一下如何確保你的工作脫離主線程運行并保證執(zhí)行。這確保在默認情況下,你的工作是同步運行的,并且在主線程之外運行。這是應(yīng)該脫離主線程運行的工作,但是,因為它與直接相關(guān),所以如果關(guān)閉應(yīng)用程序則不需要繼續(xù)。


原文地址:WorkManager Basics

原文作者:Lyla Fujiwara

譯文出自:掘金翻譯計劃

本文永久鏈接:github.com/xitu/gold-m…

譯者:Rickon

校對者:Feximin

插圖來自 Virginia Poltrack

歡迎來到我們 WorkManager 系列的第二篇文章。WorkManager 是一個 Android Jetpack 庫,當(dāng)滿足工作的約束條件時,用來運行可延遲、需要保障的后臺工作。對于許多類型的后臺工作,WorkManager 是當(dāng)前的最佳實踐方案。在第一篇博文中,我們討論了 WorkManager 是什么以及何時使用 WorkManager。

在這篇博文中,我將介紹:

將你的后臺任務(wù)定義為工作

定義特定的工作應(yīng)該如何運行

運行你的工作

使用鏈進行存在依賴的工作

監(jiān)視你的工作的狀態(tài)

我還將解釋 WorkManager 幕后發(fā)生的事情,以便你可以就如何使用它做出明智的決定。

從一個例子開始

假設(shè)你有一個圖片編輯應(yīng)用,可讓你給圖像加上濾鏡并將其上傳到網(wǎng)絡(luò)讓全世界看到。你希望創(chuàng)建一系列后臺任務(wù),這些任務(wù)用于濾鏡,壓縮圖像和之后的上傳。在每個環(huán)節(jié),都有一個需要檢查的約束——給圖像加濾鏡時要有足夠的電量,壓縮圖像時要有足夠的存儲空間,以及上傳圖像時要有網(wǎng)絡(luò)連接。

這個例子如上圖所示

這個例子正是具有以下特點的任務(wù):

可延遲的,因為你不需要它立即執(zhí)行,而且實際上可能希望等待某些約束被滿足(例如等待網(wǎng)絡(luò)連接)。

需要確保能夠運行,無論應(yīng)用程序是否退出,因為如果加了濾鏡后的圖像永遠沒能與世界共享,你的用戶會非常不滿意!

這些特點使我們的圖像加濾鏡和上傳任務(wù)成為 WorkManager 的完美用例。

添加 WorkManager 依賴

本文使用 Kotlin 書寫代碼,使用 KTX 庫(KoTlin eXtensions)。KTX 版本的庫提供了 擴展函數(shù) 為了更簡潔和習(xí)慣的使用 Kotlin。你可以添加如下依賴來使用 KTX 版本的 WorkManager:

dependencies {
 def work_version = "1.0.0-beta02"
 implementation "android.arch.work:work-runtime-ktx:$work_version"
}

你可以在 這里](developer.android.com/topic/libra…) 到該庫的最新版本。如果你想使用 Java 依賴,那就移除“-ktx”。

定義你的 work 做什么

在我們將多個任務(wù)連接在一起之前,讓我們關(guān)注如何執(zhí)行一項工作。我將會著重細說上傳任務(wù)。首先,你需要創(chuàng)建自己的 Worker 實現(xiàn)類。我將會把我們的類命名為 UploadWorker,然后重寫 doWork() 方法。

Workers:

定義你的工作實際做了什么。

接受輸入并產(chǎn)生輸出。輸入和輸出都以鍵值對表示。

始終返回表示成功,失敗或重試的值。

這是一個示例,展示了如何實現(xiàn)上傳圖像的 Worker

class UploadWorker(appContext: Context, workerParams: WorkerParameters)
    : Worker(appContext, workerParams) {

    override fun doWork(): Result {
        try {
            // Get the input
            val imageUriInput = inputData.getString(Constants.KEY_IMAGE_URI)

            // Do the work
            val response = upload(imageUriInput)

            // Create the output of the work
            val imageResponse = response.body()
            val imgLink = imageResponse.data.link
            // workDataOf (part of KTX) converts a list of pairs to a [Data] object.
            val outputData = workDataOf(Constants.KEY_IMAGE_URI to imgLink)

            return Result.success(outputData)

        } catch (e: Exception) {
            return Result.failure()
        }
    }

    fun upload(imageUri: String): Response {
        TODO(“Webservice request code here”)
        // Webservice request code here; note this would need to be run
        // synchronously for reasons explained below.
    }

}

有兩點需要注意:

輸入和輸出是作為 Data 傳遞,它本質(zhì)上是原始類型和數(shù)組的映射。Data 對象應(yīng)該相當(dāng)小 —— 實際上可以輸入/輸出的總大小有限制。這由 MAX_DATA_BYTES 設(shè)置。如果您需要將更多數(shù)據(jù)傳入和傳出 Worker,則應(yīng)將數(shù)據(jù)放在其他地方,例如 Room database。作為一個例子,我傳入上面圖像的 URI,而不是圖像本身。

在代碼中,我展示了兩個返回示例:Result.success()Result.failure()。還有一個 Result.retry() 選項,它將在之后的時間再次重試你的工作。

定義您的 work 應(yīng)該如何運行

一方面 Worker 定義工作的作用,另一方面 WorkRequest 定義應(yīng)該如何以及何時運行工作

以下是為 UploadWorker 創(chuàng)建 OneTimeWorkRequest 的示例。也可以有重復(fù)性的 PeriodicWorkRequest

// workDataOf (part of KTX) converts a list of pairs to a [Data] object.
val imageData = workDataOf(Constants.KEY_IMAGE_URI to imageUriString)

val uploadWorkRequest = OneTimeWorkRequestBuilder()
        .setInputData(imageData)
        .build()

WorkRequest 將輸入 imageData: Data 對象,并盡快運行。

假設(shè) UploadWork 并不總是應(yīng)該立即運行 —— 它應(yīng)該只在設(shè)備有網(wǎng)絡(luò)連接時運行。你可以通過添加 Constraints 對象來完成此操作。你可以創(chuàng)建這樣的約束:

val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .build()

以下是其他受支持約束的示例:

val constraints = Constraints.Builder()
        .setRequiresBatteryNotLow(true)
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .setRequiresCharging(true)
        .setRequiresStorageNotLow(true)
        .setRequiresDeviceIdle(true)
        .build()

最后,還記得 Result.retry() 嗎?我之前說過,如果 Worker 返回 Result.retry(),WorkManager 將重新計劃工作。你可以在創(chuàng)建新的 WorkRequest 時自定義退避條件。這允許你定義何時應(yīng)重試運行。

退避條件由兩個屬性定義:

BackoffPolicy,默認為指數(shù)性的,但是可以設(shè)置為線性。

持續(xù)時間,默認為 30 秒。

用于對上傳工作進行排隊的組合代碼如下,包括約束,輸入和自定義退避策略:

// Create the Constraints
val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .build()

// Define the input
val imageData = workDataOf(Constants.KEY_IMAGE_URI to imageUriString)

// Bring it all together by creating the WorkRequest; this also sets the back off criteria
val uploadWorkRequest = OneTimeWorkRequestBuilder()
        .setInputData(imageData)
        .setConstraints(constraints)        
        .setBackoffCriteria(
                BackoffPolicy.LINEAR, 
                OneTimeWorkRequest.MIN_BACKOFF_MILLIS, 
                TimeUnit.MILLISECONDS)
        .build()
運行 work

這些都很好,但你還沒有真正調(diào)度好你的工作去運行。以下是告訴 WorkManager 調(diào)度工作所需的一行代碼:

WorkManager.getInstance().enqueue(uploadWorkRequest)

你首先需要獲取 WorkManager 的實例,這是一個負責(zé)執(zhí)行你的工作的單例。調(diào)用 enqueue 來啟動 WorkManager 跟蹤和調(diào)度工作的整個過程。

在幕后 —— 工作是怎么運行的

那么,WorkManager 能為您做些什么呢?默認情況下,WorkManager 會:

脫離主線程運行你的工作(假設(shè)你正在繼承 Worker 類,如上面的 UploadWorker 所示)。

保障 你的工作將會運行(即使你重啟設(shè)備或應(yīng)用程序退出,它也不會忘記運行你的工作)。

根據(jù)用戶 API 級別的最佳實踐運行(如上一篇文章所述)。

讓我們探討一下 WorkManager 如何確保你的工作脫離主線程運行并保證執(zhí)行。在幕后,WorkManager 包括以下部分:

內(nèi)部 TaskExecutor:一個單線程 Executor,處理所有排隊工作的請求。如果您不熟悉 Executors,可以在這里閱讀更多相關(guān)信息。

WorkManager 數(shù)據(jù)庫:一個本地數(shù)據(jù)庫,可跟蹤所有工作的所有信息和狀態(tài)。這包括工作的當(dāng)前狀態(tài),工作的輸入和輸出以及對工作的任何約束限制。此數(shù)據(jù)庫使 WorkManager 能夠保證你的工作能夠完成 —— 如果你的用戶的設(shè)備重新啟動并且工作中斷,則可以從數(shù)據(jù)庫中提取工作的所有詳細信息,并在設(shè)備再次啟動時重新啟動工作。

WorkerFactory:一個默認工廠,用于創(chuàng)建 Worker 的實例。我們將在以后的博文中介紹為什么以及如何配置它。

Default Executor:一個默認的執(zhí)行程序,運行你的工作,除非你另行指定。這確保在默認情況下,你的工作是同步運行的,并且在主線程之外運行。

這些部分可以被重寫以具有不同的行為。

來自:Working with WorkManager Android 開發(fā)者大會展示 2018

當(dāng)你安排 WorkRequest

    內(nèi)部 TaskExecutor 立即將你的 WorkRequest 信息保存到 WorkManager 數(shù)據(jù)庫。

    稍后,當(dāng)滿足 WorkRequestConstraints 時(可以立即發(fā)生),Internal TaskExecutor 會告訴 WorkerFactory 創(chuàng)建一個 Worker

    之后,默認的 Executor 調(diào)用你的 WorkerdoWork() 方法脫離主線程。

通過這種方式,默認情況下,你的工作都可以保證執(zhí)行脫離主線程運行。

現(xiàn)在,如果你想使用除默認 Executor 之外的一些其他機制來運行你的工作,也是可以的!對協(xié)程(CoroutineWorker)和 RxJava(RxWorker)的開箱即用支持作為工作的手段。

或者,你可以使用 ListenableWorker 準(zhǔn)確指定工作的執(zhí)行方式。Worker 實際上是 ListenableWorker 的一個實現(xiàn),它默認在默認的 Executor 上運行你的工作,因此是同步的。所以,如果你想要完全控制工作的線程策略或異步運行工作,你可以將 ListenableWorker 子類化(具體細節(jié)將在后面的文章中討論)。

WorkManager 雖然將所有工作信息保存到數(shù)據(jù)庫中有些麻煩,但它還是會做,這使得它成了非常適合需要保障執(zhí)行的任務(wù)。這也是使得 WorkManager 輕松應(yīng)對對于不需要保障且只需要在后臺線程上執(zhí)行的任務(wù)的的原因。例如,假設(shè)你已經(jīng)下載了圖像,并且希望根據(jù)該圖像更改 UI 部分的顏色。這是應(yīng)該脫離主線程運行的工作,但是,因為它與 UI 直接相關(guān),所以如果關(guān)閉應(yīng)用程序則不需要繼續(xù)。所以在這樣的情況下,不要使用 WorkManager —— 堅持使用像 Kotlin 協(xié)程那樣輕量的東西或創(chuàng)建自己的 Executor

使用鏈進行依賴性工作

我們的濾鏡示例包含的不僅僅是一個任務(wù) —— 我們想要給多個圖像加濾鏡,然后壓縮并上傳。如果要一個接一個地或并行地運行一系列 WorkRequests,則可以使用 鏈。示例圖顯示了一個鏈,其中有三個并行運行的濾鏡任務(wù),后面是壓縮任務(wù)和上傳任務(wù),按順序運行:

使用 WorkManager 非常簡單。假設(shè)你已經(jīng)用適當(dāng)?shù)募s束創(chuàng)建了所有 WorkRequests,代碼如下所示:

WorkManager.getInstance()
    .beginWith(Arrays.asList(
                             filterImageOneWorkRequest, 
                             filterImageTwoWorkRequest, 
                             filterImageThreeWorkRequest))
    .then(compressWorkRequest)
    .then(uploadWorkRequest)
    .enqueue()

三個圖片濾鏡 WorkRequests 并行執(zhí)行。一旦完成所有濾鏡 WorkRequests (并且只有完成所有三個),就會發(fā)生 compressWorkRequest,然后是 uploadWorkRequest

鏈的另一個優(yōu)點是:一個 WorkRequest 的輸出作為下一個 WorkRequest 的輸入。因此,假設(shè)你正確設(shè)置了輸入和輸出數(shù)據(jù),就像我上面的 UploadWorker 示例所做的那樣,這些值將自動傳遞。

為了處理并行的三個濾鏡工作請求的輸出,可以使用 InputMerger,特別是 ArrayCreatingInputMerger。代碼如下:

val compressWorkRequest = OneTimeWorkRequestBuilder()
        .setInputMerger(ArrayCreatingInputMerger::class.java)
        .setConstraints(constraints)
        .build()

請注意,InputMerger 是添加到 compressWorkRequest 中的,而不是并行的三個濾鏡請求中的。

假設(shè)每個濾鏡工作請求的輸出是映射到圖像 URI 的鍵 “KEY_IMAGE_URI”。添加 ArrayCreatingInputMerger 的作用是并行請求的輸出,當(dāng)這些輸出具有匹配的時,它會創(chuàng)建一個包含所有輸出值的數(shù)組,映射到單個鍵。可視化圖表如下:

ArrayCreatingInputMerger 功能可視化

因此,compressWorkRequest 的輸入將最終成為映射到濾鏡圖像 URI 數(shù)組的 “KEY_IMAGE_URI” 對。

觀察你的 WorkRequest 狀態(tài)

監(jiān)視工作的最簡單方法是使用 LiveData 類。如果你不熟悉 LiveData,它是一個生命周期感知的可監(jiān)視數(shù)據(jù)持有者 —— 這里 對此有更詳細的描述。

調(diào)用 getWorkInfoByIdLiveData 返回一個 WorkInfoLiveDataWorkInfo 包含輸出的數(shù)據(jù)和表示工作狀態(tài)的枚舉。當(dāng)工作順利完成后,它的 State 就會是 SUCCEEDED。因此,例如,你可以通過編寫一些監(jiān)視代碼來實現(xiàn)當(dāng)工作完成時自動顯示該圖像:

// In your UI (activity, fragment, etc)
WorkManager.getInstance().getWorkInfoByIdLiveData(uploadWorkRequest.id)
        .observe(lifecycleOwner, Observer { workInfo ->
            // Check if the current works state is "successfully finished"
            if (workInfo != null && workInfo.state == WorkInfo.State.SUCCEEDED) {
                displayImage(workInfo.outputData.getString(KEY_IMAGE_URI))
            }
        })

有幾點需要注意:

每個 WorkRequest 都有一個唯一的 id,該唯一 id 是查找關(guān)聯(lián) WorkInfo 的一種方法。

WorkInfo 更改時進行監(jiān)視并被通知的能力是 LiveData 提供的功能。

工作有一個由不同 State 代表的生命周期。監(jiān)視 LiveData 時,你會看到這些狀態(tài);例如,你可能會看到:

“happy path” 或工作狀態(tài)

工作狀態(tài)經(jīng)歷的 “happy path” 如下:

    BLOCKED:只有當(dāng)工作在鏈中并且不是鏈中的下一個工作時才會出現(xiàn)這種狀態(tài)。

    ENQUEUED:只要工作是工作鏈中的下一個并且有資格運行,工作就會進入這個狀態(tài)。這項工作可能仍在等待 Constraint 被滿足。

    RUNNING:在這種狀態(tài)時,工作正在運行。對于 Worker,這意味著 doWork() 方法已經(jīng)被調(diào)用。

    SUCCEEDED:當(dāng) doWork() 返回 Result.success() 時,工作進入這種最終狀態(tài)。

現(xiàn)在,當(dāng)工作處于 RUNNING 狀態(tài),你可以調(diào)用 Result.retry()。這將會導(dǎo)致工作退回 ENQUEUED 狀態(tài)。工作也可能隨時被 CANCELLED

如果工作運行的結(jié)果是 Result.failure() 而不是成功。它的狀態(tài)將會以 FAILED 結(jié)束,因此,狀態(tài)的完整流程圖如下所示:

(來自:Working with WorkManager Android 開發(fā)者峰會 2018)

想看精彩的視頻講解,請查看 WorkManager Android 開發(fā)者峰會演講。

總結(jié)

這就是 WorkManager API 的基礎(chǔ)知識。使用我們剛剛介紹的代碼片段,你現(xiàn)在就可以:

創(chuàng)建包含輸入/輸出的 Worker。

使用 WorkRequestConstraint、啟動輸入和退出策略配置 Worker 的運行方式。

調(diào)度 WorkRequest。

了解默認情況下 WorkManager 在線程和保障運行方面的幕后工作。

創(chuàng)建復(fù)雜鏈?zhǔn)较嗷ヒ蕾嚨墓ぷ?,可以順序運行和并行運行。

使用 WorkInfo 監(jiān)視你的 WorkRequest 的狀態(tài)。

想親自試試 WorkManager 嗎?查看 codelab,包含 Kotlin 和 Java 代碼。

隨著我們繼續(xù)更新本系列,請繼續(xù)關(guān)注有關(guān) WorkManager 主題的更多博客文章。 有什么問題或者你希望我們寫到的東西嗎?請在評論區(qū)告訴我們!

感謝 Pietro Maggi

WorkManager 相關(guān)資源

官方文檔

參考指南

WorkManager 1.0.0-beta02 Release notes

Codelab:Kotlin 和 Java.

源碼(AOSP 的一部分)

Working with WorkManager (Android 開發(fā)者峰會 2018) presentation

Issue Tracker

StackOverflow 上面的 WorkManager 相關(guān)問題

Google’s Power blog post series

如果發(fā)現(xiàn)譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改并 PR,也可獲得相應(yīng)獎勵積分。文章開頭的 本文永久鏈接 即為本文在 GitHub 上的 MarkDown 鏈接。


掘金翻譯計劃 是一個翻譯優(yōu)質(zhì)互聯(lián)網(wǎng)技術(shù)文章的社區(qū),文章來源為 掘金 上的英文分享文章。內(nèi)容覆蓋 Android、iOS、前端、后端、區(qū)塊鏈、產(chǎn)品、設(shè)計、人工智能等領(lǐng)域,想要查看更多優(yōu)質(zhì)譯文請持續(xù)關(guān)注 掘金翻譯計劃、官方微博、知乎專欄。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/7044.html

相關(guān)文章

  • WorkManager入門到實踐,有這一篇就夠了

    摘要:前言上一次我們對的應(yīng)用進行了一次全面的分析,這一次我們來聊聊。 showImg(https://segmentfault.com/img/remote/1460000020077803?w=1280&h=853); 前言 上一次我們對Paging的應(yīng)用進行了一次全面的分析,這一次我們來聊聊WorkManager。 如果你對Paging還未了解,推薦閱讀這篇文章: Paging在Recy...

    bingchen 評論0 收藏0
  • [] 在 Android 使用協(xié)程(part III) - 在實際工作中使用

    摘要:通過實現(xiàn)一次請求來解釋使用協(xié)程中的實際問題是這篇文章的重點。當(dāng)接收一個新事件時,啟動一個新的協(xié)程來對列表進行排序,并在響應(yīng)時更新。在中啟動協(xié)程作為一般模式。因此,在默認情況下,在存儲庫中啟動的任何協(xié)程都會泄露。 原文鏈接:Coroutines On Android (part III): Real work 原文作者:Sean McQuillan 這是一篇關(guān)于在 Android 上使用...

    番茄西紅柿 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<