根據(jù)google官方demo,自己仿寫
google例子地址https://github.com/android/architecture-components-samples/tree/main/WorkManagerSample
MainActivity,調(diào)用位置
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<Button>(R.id.click_btn).setOnClickListener {
val continuation = TestOperations.Builder(this, "nihaoa"/*可以改為url地址等數(shù)據(jù)*/)
.setFirstWorker(true)
.setTwoWorker(true)
.build()
continuation.continuation.enqueue()
}
}
//簡單的單任務處理
// val myWorkRequest = OneTimeWorkRequestBuilder<GetNetData>()
// .setInputData(workDataOf("ImageUrl" to "test"))
// .setBackoffCriteria(
// BackoffPolicy.LINEAR,
// OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
// TimeUnit.MILLISECONDS
// )
// .build()
//
// WorkManager.getInstance(this).enqueue(myWorkRequest)
}
BaseWorker類,用來做多個任務的組合,類似責任鏈模式
abstract class BaseWorker(context: Context, parameters: WorkerParameters) :
CoroutineWorker(context, parameters) {
override suspend fun doWork(): Result {
val resourceUri = inputData.getString(Constants.KEY_IMAGE_URI)//獲取傳遞過來的數(shù)據(jù)
try {
applyFilter(resourceUri!!)
return Result.success()
} catch (throwable: Throwable) {
return Result.failure()
}
}
abstract fun applyFilter(input: String): String
}
FirstWroker類,第一個任務類,繼承BaseWorker,實現(xiàn)applyFilter方法
class FirstWroker(appContext: Context, workerParams: WorkerParameters) :
BaseWorker(appContext, workerParams) {
override fun applyFilter(input: String): String {
var s = input+1;
Log.d("testStr==1",s)
return s
}
}
TwoWorker類,第二個任務類,同樣繼承BaseWorker,實現(xiàn)applyFilter方法(和第一個沒什么區(qū)別)
class TwoWorker(context: Context, parameters: WorkerParameters) : BaseWorker(context, parameters) {
override fun applyFilter(input: String): String {
var s = input + 2
Log.d("testStr==2", s)
return s
}
}
TestOperations類,管理工作流程,比較重要,如果是多任務模式
class TestOperations constructor(val continuation: WorkContinuation) {
class Builder(val mContext: Context, val testStr: String) {
private var startFirst1: Boolean = false
private var startTow2: Boolean = false
fun setFirstWorker(startFirst: Boolean): Builder {
startFirst1 = startFirst//
return this
}
fun setTwoWorker(startTow: Boolean): Builder {
startTow2 = startTow
return this
}
fun build(): TestOperations {
var continuation = WorkManager.getInstance(mContext)
.beginUniqueWork(
Constants.TEST_KEY,
ExistingWorkPolicy.REPLACE,
OneTimeWorkRequest.from(CancelWorker::class.java)
)//創(chuàng)建并添加多任務,beginUniqueWork可以放入多個不重復的任務,beginWith可以放入重復的
if (startFirst1) {
val test = OneTimeWorkRequestBuilder<FirstWroker>()
.setInputData(createInputData())
.build()
continuation = continuation.then(test)//添加第一個任務,由于每個都繼承BaseWorker,所以都會走Base的doWork方法
}
if (startTow2) {
val test2 = OneTimeWorkRequestBuilder<TwoWorker>()
.setInputData(createInputData())
.build()
continuation = continuation.then(test2)//添加第二個任務,由于每個都繼承BaseWorker,所以都會走Base的doWork方法
}
return TestOperations(continuation)//返回給MainActivity,使MainActivity可以控制什么時候使用enqueue入隊開啟
}
private fun createInputData(): Data {
//鍵值對獲取地址參數(shù),傳遞給不同的工作線程,比如google demo傳遞的是圖片地址,所以會依次對圖片做不同處理,順序執(zhí)行
//如果為了獲取上一個處理完的結果數(shù)據(jù),理論上是可以通過鍵值對存儲,依次修改,具體沒有測試過
return workDataOf(Constants.KEY_IMAGE_URI to testStr)
}
}
}
Constants,通用KEY
object Constants {
const val TEST_KEY:String = "test_key" ;
const val KEY_IMAGE_URI = "KEY_IMAGE_URI"
}
CancelWorker,做一些準備工作
class CancelWorker(context: Context, workerParams: WorkerParameters) :
Worker(context, workerParams) {
override fun doWork(): Result {
//做一些準備工作
return Result.success()
}
}