Architecture -- WorkManager

1. WorkManager

1). 簡(jiǎn)介

其實(shí)就是"管理一些要在后臺(tái)工作的任務(wù), -- 即使你的應(yīng)用沒啟動(dòng)也能保證任務(wù)能被執(zhí)行"我纪,WorkManager在底層, 會(huì)根據(jù)你的設(shè)備情況, 選用JobScheduler, Firebase的JobDispatcher, 或是AlarmManager转晰。WorkManager并不是為了那種在應(yīng)用內(nèi)的后臺(tái)線程而設(shè)計(jì)出來(lái)的. 這種需求你應(yīng)該使用ThreadPool污它。

2). 引入
  • kolin
# Android Studio 3.0吏祸, 3.0以下版本請(qǐng)使用complie
  ext.work_version = "1.0.0-alpha02"
  // WorkManager
  implementation "android.arch.work:work-runtime:$work_version" // use -ktx for Kotlin
  // optional - Firebase JobDispatcher support
  implementation "android.arch.work:work-firebase:$work_version"
  // optional - Test helpers
  androidTestImplementation "android.arch.work:work-testing:$work_version"
  • java
# 必須加入
implementation "android.arch.work:work-runtime:1.0.0-alpha01"

2. 用法

1). 執(zhí)行一次的任務(wù)
  • PullWorker.kt
/**
 * Pull 任務(wù)
 * 創(chuàng)建步驟:
 *      1. 繼承Worker類
 *      2. 重寫doWork()方法
 * Created by mazaiting on 2018/6/6.
 */
class PullWorker : Worker() {
    override fun doWork(): WorkerResult {
        // 模擬設(shè)置頁(yè)面中的"是否接受推送"是否被勾選
        val isOkay = this.inputData.getBoolean("key_accept_bg_work", false)

        // 判斷是否推送
        if (isOkay) {
            // 模擬長(zhǎng)時(shí)間工作
            Thread.sleep(5000)
            // 獲取數(shù)據(jù)
            val pulledResult = startPull()
            // 設(shè)置輸出數(shù)據(jù)
            val output = Data.Builder().putString("key_pulled_result", pulledResult).build()
            // 存放數(shù)據(jù)
            outputData = output
            // 返回成功
            return WorkerResult.SUCCESS
        } else {
            // 返回失敗
            return WorkerResult.FAILURE
        }
    }

    /**
     * 開始推送
     */
    private fun startPull(): String {
        return "[worker] pull messages from backend."
    }

}
  • PullEngine.kt
/**
 * Pull 引擎
 * Created by mazaiting on 2018/6/6.
 */
class PullEngine {

    fun scheduleOneTimeWork(context: Context) {
        // 設(shè)置任務(wù)脑沿,執(zhí)行一次
        val pullRequest = OneTimeWorkRequestBuilder<PullWorker>()
                .setInputData(
                        Data.Builder()
                                .putBoolean("key_accept_bg_work", true)
                                .build()
                )
                .build()
        WorkManager.getInstance().enqueue(pullRequest)
        // 將請(qǐng)求入列
        WorkManager.getInstance().enqueue(pullRequest)
        // 獲取請(qǐng)求ID
        val pullRequestId = pullRequest.id
        // 存在SharedPreference中
        PreferenceManager
                .getDefaultSharedPreferences(context)
                .edit()
                .putString("pullId", pullRequestId.toString())
                .apply()
    }

}
  • MainApplication.kt(注意在AndroidManifest.xml文件中配置)
class MainApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        // 任務(wù)執(zhí)行一次
        PullEngine().scheduleOneTimeWork(this.applicationContext)
    }
}
  • MainActivity.kt
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // UUID實(shí)現(xiàn)了Serializable接口徘钥,能由toString(),fromString()與String互轉(zhuǎn)
        val uuid = UUID.fromString(
                PreferenceManager.getDefaultSharedPreferences(this.applicationContext)
                        .getString("pullId", "")
        )
        WorkManager.getInstance()
                // 獲取狀態(tài)ID
                .getStatusById(uuid)
                // 觀察數(shù)據(jù)
                .observe(this, Observer<WorkStatus>{ status ->
                    if (null != status && status.state.isFinished) {
                        val pulledResult = status.outputData.getString("key_pulled_result","")
                        Log.e("MainActivity", pulledResult)
                    }
                })
    }
}
  • 打印結(jié)果


    圖1.png
2). 任務(wù)設(shè)置約束
    fun scheduleOneTimeWork(context: Context) {
        val constraints = Constraints.Builder()
                // 負(fù)荷
                .setRequiresCharging(true)
                .build()
        // 設(shè)置任務(wù)派殷,執(zhí)行一次
        val pullRequest = OneTimeWorkRequestBuilder<PullWorker>()
                // 設(shè)置約束
                .setConstraints(constraints)
                // 輸入數(shù)據(jù)
                .setInputData(
                        Data.Builder()
                                .putBoolean("key_accept_bg_work", true)
                                .build()
                )
                .build()
        // 將請(qǐng)求入列
        WorkManager.getInstance().enqueue(pullRequest)
        // 獲取請(qǐng)求ID
        val pullRequestId = pullRequest.id
        // 存在SharedPreference中
        PreferenceManager
                .getDefaultSharedPreferences(context)
                .edit()
                .putString("pullId", pullRequestId.toString())
                .apply()
    }
3). 取消任務(wù)
    // 獲取請(qǐng)求ID
    val pullRequestId = pullRequest.id
    // 取消任務(wù)
    WorkManager.getInstance().cancelWorkById(pullRequestId)
4). 任務(wù)鏈
WorkManager.getInstance()
    .beginWith(workA)
        // Note: WorkManager.beginWith() returns a
        // WorkContinuation object; the following calls are
        // to WorkContinuation methods
    .then(workB)    // FYI, then() returns a new WorkContinuation instance
    .then(workC)
    .enqueue()

WorkManager.getInstance()
    // First, run all the A tasks (in parallel):
    .beginWith(workA1, workA2, workA3)
    // ...when all A tasks are finished, run the single B task:
    .then(workB)
    // ...then run the C tasks (in any order):
    .then(workC1, workC2)
    .enqueue()

再或

val chain1 = WorkManager.getInstance()
    .beginWith(workA)
    .then(workB)
val chain2 = WorkManager.getInstance()
    .beginWith(workC)
    .then(workD)
val chain3 = WorkContinuation
    .combine(chain1, chain2)
    .then(workE)
chain3.enqueue()
5). 定時(shí)任務(wù)
    /**
     * 執(zhí)行任務(wù)
     */
    fun schedulePeriodicWork(context: Context) {
        val constraints = Constraints.Builder()
                // 負(fù)荷
                .setRequiresCharging(true)
                .build()
        // 設(shè)置任務(wù)執(zhí)行時(shí)長(zhǎng)茴肥,并設(shè)置輸入?yún)?shù)
        // 長(zhǎng)期任務(wù)坚踩,循環(huán)
        val pullRequest = PeriodicWorkRequestBuilder<PullWorker>(30, TimeUnit.SECONDS)
                            .setConstraints(constraints)
                            .setInputData(
                                Data.Builder()
                                        .putBoolean("key_accept_bg_work", true)
                                        .build()
                            )
                            .build()
        // 將請(qǐng)求入列
        WorkManager.getInstance().enqueue(pullRequest)
        // 獲取請(qǐng)求ID
        val pullRequestId = pullRequest.id
        // 存在SharedPreference中
        PreferenceManager
                .getDefaultSharedPreferences(context)
                .edit()
                .putString("pullId", pullRequestId.toString())
                .apply()
    }
6). 原文地址
7). 代碼下載
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市瓤狐,隨后出現(xiàn)的幾起案子瞬铸,更是在濱河造成了極大的恐慌批幌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嗓节,死亡現(xiàn)場(chǎng)離奇詭異荧缘,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)拦宣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門截粗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人鸵隧,你說(shuō)我怎么就攤上這事绸罗。” “怎么了掰派?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵从诲,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我靡羡,道長(zhǎng)系洛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任略步,我火速辦了婚禮描扯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘趟薄。我一直安慰自己绽诚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布杭煎。 她就那樣靜靜地躺著恩够,像睡著了一般。 火紅的嫁衣襯著肌膚如雪羡铲。 梳的紋絲不亂的頭發(fā)上蜂桶,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音也切,去河邊找鬼扑媚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛雷恃,可吹牛的內(nèi)容都是我干的疆股。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼倒槐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼旬痹!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤唱凯,失蹤者是張志新(化名)和其女友劉穎羡忘,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體磕昼,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年节猿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了票从。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡滨嘱,死狀恐怖峰鄙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情太雨,我是刑警寧澤吟榴,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站囊扳,受9級(jí)特大地震影響吩翻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜锥咸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一狭瞎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧搏予,春花似錦熊锭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至速缨,卻和暖如春锌妻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸟廓。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工从祝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人引谜。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓牍陌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親员咽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子毒涧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354