Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android后台每分钟从网页加载数据_Android_Alarmmanager_Background Process_Android Workmanager_Android Jobscheduler - Fatal编程技术网

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

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。然而,到目前为止

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

从设备启动的那一刻起,它应该每分钟从网页上加载数据。它使用XmlPullParser和一个简单的URL inputstream。它只有10kb,所以没有那么密集。我认为这类任务被称为延期。用户打开应用程序后,活动必须能够访问流程加载的信息。后台进程还需要能够在数据显示某些结果时发出通知

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

我无权访问应用程序所连接的服务器。所以我不能做FirebaseMessaging服务

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

活动如何最好地与该流程交换信息?

我愿意接受所有建议,
感谢您抽出时间。

轻松使用
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录制的。