Android 定时任务
源码
配置
gradle/libs.versions.toml
[versions]
work = "2.11.0"
[libraries]
androidx-work-runtime-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "work" }
app/build.gradle.kts
dependencies {
implementation(libs.androidx.work.runtime.ktx)
}
MinuteTaskService
package cn.com.xuxiaowei.service
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.os.SystemClock
import android.text.format.DateFormat
import cn.com.xuxiaowei.utils.FileLogger
class MinuteTaskService : Service() {
private val handler = Handler(Looper.getMainLooper())
private val task = object : Runnable {
override fun run() {
val now = DateFormat.format("yyyy-MM-dd HH:mm:ss", System.currentTimeMillis())
FileLogger.log(
this@MinuteTaskService,
"service",
"MinuteTaskService",
"每分钟任务执行: $now, uptime=${SystemClock.uptimeMillis()}"
)
handler.postDelayed(this, 60_000)
}
}
override fun onCreate() {
super.onCreate()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
handler.removeCallbacks(task)
handler.post(task)
return START_STICKY
}
override fun onDestroy() {
handler.removeCallbacks(task)
super.onDestroy()
}
override fun onBind(intent: Intent?) = null
companion object {
fun start(context: Context) {
context.startService(Intent(context, MinuteTaskService::class.java))
}
}
}
FifteenMinuteWorker
package cn.com.xuxiaowei.worker
import android.content.Context
import android.os.SystemClock
import androidx.work.CoroutineWorker
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import cn.com.xuxiaowei.utils.FileLogger
import java.util.concurrent.TimeUnit
class FifteenMinuteWorker(
appContext: Context,
params: WorkerParameters
) : CoroutineWorker(appContext, params) {
override suspend fun doWork(): Result {
val uptime = SystemClock.uptimeMillis()
FileLogger.log(
applicationContext,
"worker",
"FifteenMinuteWorker",
"每15分钟任务执行, uptime=$uptime"
)
return Result.success()
}
companion object {
private const val UNIQUE_NAME = "cn.com.xuxiaowei.FifteenMinuteWorker"
fun schedule(context: Context) {
val request = PeriodicWorkRequestBuilder<FifteenMinuteWorker>(
15, TimeUnit.MINUTES
).build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
UNIQUE_NAME,
ExistingPeriodicWorkPolicy.KEEP,
request
)
}
}
}
App
package cn.com.xuxiaowei
import android.app.Application
import android.os.Build
import cn.com.xuxiaowei.service.MinuteTaskService
import cn.com.xuxiaowei.utils.FileLogger
import cn.com.xuxiaowei.worker.FifteenMinuteWorker
class App : Application() {
override fun onCreate() {
super.onCreate()
val appVersion = try {
val pm = packageManager
val pi = pm.getPackageInfo(packageName, 0)
val versionName = pi.versionName ?: "unknown"
val versionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
pi.longVersionCode.toString()
} else {
@Suppress("DEPRECATION")
pi.versionCode.toString()
}
"$versionName($versionCode)"
} catch (e: Exception) {
"unknown"
}
val deviceInfo = "model=${Build.MODEL}, brand=${Build.BRAND}, sdk=${Build.VERSION.SDK_INT}"
FileLogger.log(this, "startup", "App", "App started version=$appVersion, $deviceInfo")
MinuteTaskService.start(this)
FifteenMinuteWorker.schedule(this)
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".App"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Xuxiaowei">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.Xuxiaowei">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".service.MinuteTaskService"
android:exported="false" />
</application>
</manifest>
查看日志
- 启动日志
service 日志
worker 日志