[英]Android background process loading data from webpage every minute
我正在开发一个具有不断重复后台进程的 Android 应用程序。
从设备启动的那一刻起,它应该每分钟从网页加载数据。 它使用 XmlPullParser 和一个简单的 URL 输入流。 它只有 10kb,所以不是那么密集。 我相信这种任务被称为延迟。 一旦用户打开应用程序,该进程加载的信息必须可供 Activity 访问。 一旦数据显示某些结果,后台进程也需要能够发出通知。
在 Android 中似乎有多种方法可以实现这一点,例如。 JobScheduler、WorkManager 或 AlarmManager 但是到目前为止我尝试过的一切似乎要么在活动关闭时停止,要么根本不运行。 每分钟的时间似乎也是一个问题,因为对于重复工作和工人来说,最小间隔是 15。这一分钟不必精确。 我想,与其让一个重复的过程加载数据,不如让一个长时间运行的进程在加载数据之间休眠 1m 可能会更好。
我无权访问应用程序连接的服务器。 所以我不能做 FirebaseMessagingService。
安排这样一个后台进程的最佳方式是什么?
活动如何最好地与该流程交换信息?
我愿意接受所有建议,感谢您的宝贵时间。
使用WorkManager
很容易,这是在 Android 中调度重复后台工作最受鼓励的方式,请参阅介绍。
正如您所说,最小重复工作请求间隔限制为15 分钟,打破它的唯一方法是重复安排一次性工作。
1. 设置你的 Worker Class:
class ToastShower(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
withContext(Dispatchers.Main) { //ui related work must run in Main thread!!
Toast.makeText(applicationContext, "Hey, I'm Sam! This message will appear every 5 seconds.", Toast.LENGTH_SHORT).show()
}
return Result.success()
}
}
2. 设置您的自定义应用程序 Class:
class WorkManagerApplication : Application() {
private val backgroundScope = CoroutineScope(Dispatchers.Default) //standard background thread
private val applicationContext = this
override fun onCreate() { //called when the app launches (same as Activity)
super.onCreate()
initWork()
}
private fun initWork() {
backgroundScope.launch { //all rnu in background thread
setupToastShowingWork(0) //no delay at first time
observeToastShowingWork() //observe work state changes, see below
}
}
private fun setupToastShowingWork(delayInSeconds: Long) { //must run in background thread
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED) //when using WiFi
.build()
val oneTimeRequest = OneTimeWorkRequestBuilder<ToastShower>() //【for breaking 15 minutes limit we have to use one time request】
.setInitialDelay(delayInSeconds, TimeUnit.SECONDS) //customizable delay (interval) time
.setConstraints(constraints)
.build()
WorkManager.getInstance(applicationContext).enqueueUniqueWork( //【must be unique!!】
ToastShower::class.java.simpleName, //work name, use class name for convenient
ExistingWorkPolicy.KEEP, //if new work comes in with same name, discard the new one
oneTimeRequest
)
}
private suspend fun observeToastShowingWork() {
withContext(Dispatchers.Main) { //must run in Main thread for using observeForever
WorkManager.getInstance(applicationContext).getWorkInfosForUniqueWorkLiveData(ToastShower::class.java.simpleName).observeForever {
if (it[0].state == WorkInfo.State.SUCCEEDED) { //when the work is done
backgroundScope.launch { //prevent from running in Main thread
setupToastShowingWork(5) //every 5 seconds
}
}
}
}
}
}
3.设置AndroidManifest文件:
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.workmanagertest">
<application
android:name=".WorkManagerApplication" //【here, must!!!】
...
</application>
</manifest>
通过以上设置,无论应用程序处于前台还是后台或被系统杀死,工作(在我的示例中显示Toast
)将每 5 秒执行一次(或者更清楚地,调度和执行)。 阻止它的唯一方法是在应用程序设置中卸载或 go 以强制关闭它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.