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()
}