Android 后台进程每分钟从网页加载数据

Android background process loading data from webpage every minute

我正在开发一个 Android 具有不断重复后台进程的应用程序。

从设备启动的那一刻起,它应该每分钟从网页加载数据。它使用 XmlPullParser 和一个简单的 URL 输入流。它只有 10kb,所以它不是那么密集。我相信这种任务被称为延迟。一旦用户打开应用程序,Activity 就必须能够访问进程加载的信息。一旦数据显示某些结果,后台进程也需要能够发出通知。

在 Android 中似乎有多种方法可以实现这一点,例如。 JobScheduler、WorkManager 或 AlarmManager 但是我到目前为止尝试的所有操作似乎在 activity 关闭或根本不 运行 时停止。每分钟的时间似乎也是一个问题,因为对于重复的工作和工人来说,最小间隔是 15。这一分钟不一定是准确的。我想象与其让一个重复的进程加载数据,不如让一个长的 运行ning 进程在加载数据之间休眠 1m 可能更好。

我无权访问应用程序正在连接的服务器。所以我不能执行 FirebaseMessagingService。

安排此类后台进程的最佳方式是什么?

activity如何与该进程最好地交换信息?

我愿意接受所有建议, 谢谢你的时间。

轻松使用 WorkManager,这是 安排重复 后台工作最受鼓励的方式 Android,请参阅 introduction

如您所说,最小重复工作请求间隔限制为 15 minutes,打破它的唯一方法是 重复 安排 一次性工作.

1.设置你的工人 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。设置 Android清单文件:

<manifest 
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.workmanagertest">

    <application
        android:name=".WorkManagerApplication"                  //【here, must!!!】
    
        ...

    </application>

</manifest>

通过上面的设置,工作(在我的示例中显示 Toast)将每 5 秒执行一次(或更明确地说,安排和执行)无论应用程序是否处于前台或后台或被系统杀死。停止它的唯一方法是卸载或进入应用程序的设置以强制关闭它。

演示:https://youtu.be/7IsQQppKqFs