Android后台每分钟从网页加载数据
我正在开发一个Android应用程序,它有一个不断重复的后台进程 从设备启动的那一刻起,它应该每分钟从网页上加载数据。它使用XmlPullParser和一个简单的URL inputstream。它只有10kb,所以没有那么密集。我认为这类任务被称为延期。用户打开应用程序后,活动必须能够访问流程加载的信息。后台进程还需要能够在数据显示某些结果时发出通知 在Android中,似乎有多种方法可以实现这一点,例如JobScheduler、WorkManager或AlarmManager。然而,到目前为止,我尝试的所有方法似乎要么在活动关闭后停止,要么根本不运行。每分钟的时间安排似乎也是一个问题,因为对于重复工作和工人来说,最小间隔是15分钟。这一分钟不一定要精确。我想,与其让一个重复的进程一次加载数据,不如让一个长时间运行的进程在加载数据之间休眠1m 我无权访问应用程序所连接的服务器。所以我不能做FirebaseMessaging服务 安排此类后台流程的最佳方式是什么? 活动如何最好地与该流程交换信息? 我愿意接受所有建议,Android后台每分钟从网页加载数据,android,alarmmanager,background-process,android-workmanager,android-jobscheduler,Android,Alarmmanager,Background Process,Android Workmanager,Android Jobscheduler,我正在开发一个Android应用程序,它有一个不断重复的后台进程 从设备启动的那一刻起,它应该每分钟从网页上加载数据。它使用XmlPullParser和一个简单的URL inputstream。它只有10kb,所以没有那么密集。我认为这类任务被称为延期。用户打开应用程序后,活动必须能够访问流程加载的信息。后台进程还需要能够在数据显示某些结果时发出通知 在Android中,似乎有多种方法可以实现这一点,例如JobScheduler、WorkManager或AlarmManager。然而,到目前为止
感谢您抽出时间。轻松使用
WorkManager
,这是最受鼓励的在Android中安排重复背景工作的方法,请参阅
正如您所说,最小重复工作请求间隔被限制为,打破它的唯一方法是重复安排一次性工作
1。设置您的工人阶级:
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()
}
}
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
}
}
}
}
}
}
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.workmanagertest">
<application
android:name=".WorkManagerApplication" //【here, must!!!】
...
</application>
</manifest>
2。设置自定义应用程序类:
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()
}
}
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
}
}
}
}
}
}
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.workmanagertest">
<application
android:name=".WorkManagerApplication" //【here, must!!!】
...
</application>
</manifest>
class WorkManagerApplication:Application(){
private val backgroundScope=CoroutineScope(Dispatchers.Default)//标准后台线程
private val applicationContext=this
覆盖应用程序启动时调用的fun onCreate(){//(与活动相同)
super.onCreate()
初始化工作()
}
私人娱乐工作(){
backgroundScope.launch{//后台线程中的所有rnu
setupToastShowingWork(0)//第一次没有延迟
observeToastShowingWork()//观察工作状态的更改,请参见下文
}
}
私人娱乐设置到展示工作(delayUnseconds:Long){//必须在后台线程中运行
val constraints=constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED)//使用WiFi时
.build()
val oneTimeRequest=OneTimeWorkRequestBuilder()/【对于超过15分钟的限制,我们必须使用一次请求】
.setInitialDelay(DelayUnseconds,TimeUnit.SECONDS)//可自定义的延迟(间隔)时间
.setConstraints(约束)
.build()
WorkManager.getInstance(applicationContext).enqueueUniqueWork(/[必须是唯一的!!]
ToastShower::class.java.simpleName,//工作名,使用类名方便
ExistingWorkPolicy.KEEP,//如果新工作具有相同的名称,则放弃新工作
一次性请求
)
}
私人娱乐观看表演作品(){
withContext(Dispatchers.Main){//必须在主线程中运行才能使用ObserveForver
WorkManager.getInstance(applicationContext).getWorkInfo运行IQueWorkLiveData(ToastShower::class.java.simpleName).observeForver{
如果(它[0].state==WorkInfo.state.successed){//当工作完成时
backgroundScope.launch{//防止在主线程中运行
设置为显示工作(5)//每5秒
}
}
}
}
}
}
3。安装AndroidManifest文件:
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()
}
}
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
}
}
}
}
}
}
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.workmanagertest">
<application
android:name=".WorkManagerApplication" //【here, must!!!】
...
</application>
</manifest>
所有设备都将尝试停止应用程序,因为它会消耗电池。唯一对我有用的就是firebase云消息。您可以发送触发FirebaseMessagingService的数据类型消息。这似乎是唯一一个没有被Android扼杀的服务。如果你需要每分钟都这样做,你可能需要在你的服务器上设置一个CRON任务。你有没有试过在实际应用中设置这个任务?我所有使用WorkManager的努力都以失败告终。几分钟后,它就停止了——特别是在三星设备上。@MarkWalczak你看过我的演示视频了吗?我所有的演示都是从我的三星Galaxy Note 9录制的。