使用WorkManager
def versions = "2.7.1"
implementation "androidx.work:work-runtime:$versions"
簡單示例,并對重要方法做說明
object TsmWorkManagerTest {
private const val TAG_WORKER="tsm_work_tag"
@JvmStatic
fun tsmWorkManger(context: Context){
/**
* 重點-->1
* WorkManager 自身維護(hù)了一套數(shù)據(jù)庫,所以已經(jīng)添加的任務(wù)即使進(jìn)程結(jié)束了,
* 在下一次App啟動時,也會自動啟用,也就是同一個任務(wù)如果沒有必要,我們是不用添加第二次的,
* 所以為了避免同一個周期任務(wù)被多次添加,可以使用
* WorkManager.getInstance(context.applicationContext)
* .enqueueUniquePeriodicWork("MyUniqueWorkName",ExistingPeriodicWorkPolicy.KEEP,myWork)
* 來添加周期性的任務(wù),
* 參數(shù)1->MyUniqueWorkName 任務(wù)名稱,開發(fā)者自定義,這個方法就是通過這個字段來區(qū)別是否是同一個任務(wù),不關(guān)注任務(wù)名稱
* 參數(shù)2->ExistingPeriodicWorkPolicy.KEEP keep 的含義是當(dāng)?shù)诙€周期性任務(wù)來臨時,保持原有任務(wù),放棄新的任務(wù) 同時還有replace
* 參數(shù)3->myWork 任務(wù)
*
*
* 重點-->2
* 調(diào)用 WorkManager.getInstance(context.applicationContext).cancelAllWorkByTag 后
* 再次獲取任務(wù)的個數(shù)還是之前的個數(shù),也就是 cancel 只是讓任務(wù)不能執(zhí)行了,并沒有將任務(wù)從
* 任務(wù)隊列中移除,
*/
var workers= WorkManager.getInstance(context.applicationContext).getWorkInfosByTag(
TAG_WORKER
)
TsmLogUtils.i("任務(wù)個數(shù):${workers.get().size}")
if(workers.get().size ==0){
var builder= Constraints.Builder()
builder.setRequiredNetworkType(NetworkType.CONNECTED)//有網(wǎng)
.setRequiresBatteryNotLow(true)//電量充足
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// builder.setRequiresDeviceIdle(true)//空閑
// }
//20秒執(zhí)行一次,彈性5秒執(zhí)行
val uploadWorkRequest = PeriodicWorkRequest.Builder(TsmWorker::class.java, 5, TimeUnit.SECONDS)
.setConstraints(builder.build())
.addTag(TAG_WORKER)
.build()
//
WorkManager.getInstance(context.applicationContext).enqueue(uploadWorkRequest)
}else{
TsmLogUtils.i("任務(wù)狀態(tài):${workers.get()[0].state}")
}
//上面的是通過判斷個數(shù)來執(zhí)行的,但是這么操作對于一個周期性任務(wù)是不可控的,那么我們?nèi)绾蝸肀苊饽?
//答案就是上面的重點1中介紹的enqueueUniquePeriodicWork 這個方法
}
}
class TsmWorker : Worker {
/**
* 這個是用來判斷每次執(zhí)行的時候是否是同一個worker,
* 通過驗證得到的答案是否定的,每次重新執(zhí)行都是一個不同的對象,應(yīng)該是反射生成的
*/
private var tsm_tag:Int= Random().nextInt(50)
constructor(context: Context,workerParameters: WorkerParameters):super(context,workerParameters)
override fun doWork(): Result {
TsmLogUtils.i("定期任務(wù)$tsm_tag:-->${formatTime()} 是否是主線程:${Looper.getMainLooper() == Looper.myLooper()}")
return Result.success()
}
private fun formatTime():String{
return SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date(System.currentTimeMillis()))
}
}