如何正确使用WorkManager
Android Jetpack中的新功能来安排每天一次的定期工作,这应该每天做一次并且只做一次?
我们的想法是检查具有给定标签的工作是否已经存在WorkManager
,否则开始新的定期工作.
我尝试使用下一种方法来做到这一点:
public static final String CALL_INFO_WORKER = "Call worker";
...
WorkManager workManager = WorkManager.getInstance();
List<WorkStatus> value = workManager.getStatusesByTag(CALL_INFO_WORKER).getValue();
if (value == null) {
WorkRequest callDataRequest = new PeriodicWorkRequest.Builder(CallInfoWorker.class,
24, TimeUnit.HOURS, 3, TimeUnit.HOURS)
.addTag(CALL_INFO_WORKER)
.build();
workManager.enqueue(callDataRequest);
}
Run Code Online (Sandbox Code Playgroud)
但value
总是空,即使我把一个断点里面Worker
的doWork()
方法(所以它肯定是正在进行中),并从另一个线程检查工作状态.
android android-architecture-components android-jetpack android-workmanager
我们注意到AlarmManagerCompat
,由于AlarmManager
不同版本的操作系统中的行为不同,仅在我们的应用程序中实现警报/提醒功能并不是一种可靠的方法.(例如,打盹模式)
最初,我们计划使用Evernote的android-job库来帮助我们在应用程序中实现警报/提醒功能.
但是,在此过程中,我们也注意到谷歌刚刚发布WorkerManager
.
到目前为止,WorkerManager
当我们在应用程序退出后运行一些一次性后台作业(几乎是即时的,具有互联网连接约束)时,对我们来说效果很好.
我们计划使用WorkerManager
实现警报/提醒功能.
我想知道,WorkerManager
实现这样的功能有多可靠?有人尝试过吗?我们的目标是API 15及更高版本.
我有一个Worker
需要每24小时运行一次的实例,考虑到PeriodicWorkRequest
API ,这很简单.但这是抓住了.
如果用户在下午8点开始工作,我需要工作管理器的第一个实例在第二天早上9点运行,然后遵循24小时定期约束.
我看了一下这里,我发现OneTimeWorkRequest API有一个setInitialDelay()
可以使用的功能,但我无法找到任何PeriodicWork
API.
这是一些hacks,例如我可以使用OneTimeWork
初始延迟,然后PeriodicWork
从那里安排一个但是它有点肮脏的黑客.
有没有办法只用PeriodicWorkRequest
API 来做到这一点?
我正在构建一个功能,允许商家设置他们的业务时间表。这种功能将变量自动改变open
到true
和false
相应时代商家设置在一周中的每一天。因此,总共有 14 个可能的不同时间。
我正在尝试构建一个循环后台任务,使用新的 Android 架构组件库 WorkManager 来完成这样的事情。
val scheduleStartWork = PeriodicWorkRequest.Builder(ScheduleWorker::class.java, 7, TimeUnit.DAYS)
.setInputData(Data.Builder().putBoolean("isStart", true).build())
.setScheduleRequestedAt(diff_time, TimeUnit.MILLISECONDS)
.addTag(weekdays[index])
.build()
Run Code Online (Sandbox Code Playgroud)
不过,它给了我以下 APILibraryException 错误:
Builder.setScheduleRequestedAt 只能从同一个库组中调用
我的问题:
1)setScheduleRequestedAt
如果我想延迟调度,这是正确的调用方法diff_time
吗?
2)如果是这样,我该如何解决这个问题?
PS:diff_time
是与用户设置的每一天的每个相应小时的差异,以毫秒为单位。示例:周一至周五 = 08:00,周六至周日 = 10:00。
android kotlin android-architecture-components android-workmanager
当我将 WorkManager 从“2.2.0”升级到“2.3.0-rc01”时,出现以下新错误
当我导出 APK 时发生错误。
C:\app: Error: Remove androidx.work.impl.WorkManagerInitializer from your AndroidManifest.xml when using on-demand initialization. [RemoveWorkManagerInitializer]
Explanation for issues of type "RemoveWorkManagerInitializer":
If an android.app.Application implements
androidx.work.Configuration.Provider,
the default androidx.work.impl.WorkManagerInitializer needs to be removed
from the
AndroidManifest.xml file.
Run Code Online (Sandbox Code Playgroud)
我不知道为什么我在 2.2.0 中没有收到这样的错误,因为从 2.1.0 开始引入了“按需初始化”。
我不确定将以下内容包含在我的AndroidManifest.xml
.
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
Run Code Online (Sandbox Code Playgroud)
目前,以下是我的Application
班级。
public class MyApplication extends MultiDexApplication implements Configuration.Provider {
private static MyApplication me;
@Override
public void onCreate() {
super.onCreate();
me = …
Run Code Online (Sandbox Code Playgroud) 我想收集用户浏览数据以用于 Flutter 应用程序的离线后端分析。做到这一点的最佳方法是什么?
我计划做的是在使用WorkManager包上传它的应用程序上运行每日 cron。
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
Workmanager().initialize(uploadUserData, isInDebugMode: true);
Workmanager()
.registerOneOffTask('1', 'task1', initialDelay: Duration(seconds: 10));
runApp(MyApp());
}
void uploadUserData() {
Workmanager().executeTask((task, inputData) {
firebase_storage.FirebaseStorage.instance
.ref('/uploads/test_workmanager.txt')
.putString('workmanager test');
return Future.value(true);
});
}
Run Code Online (Sandbox Code Playgroud)
我在运行上述代码时遇到以下问题
E/BackgroundWorker( 6733): errorCode: error, errorMessage: [core/no-app]没有创建 Firebase 应用程序“[DEFAULT]” - 调用 Firebase.initializeApp()
I / WM-WorkerWrapper(6733):工作结果失败[id = 81642715-826f-4d40-b8ec-9d86eab75136,tags = {be.tramckrijte.workmanager.BackgroundWorker}]
我在调用 workmanager 任务之前以多种方式检查了 firebase 是否已初始化(使用firebase.apps.length
& .whenComplete
)
更新:许多人怀疑 firebase 连接是否正确:基本上,如果我只是调用firebase_storage....putString
inmain()
而不是 inside ,一切都会正常工作Workmanager().executeTask
。所以,麻烦只是由于 …
我想在每次用户在数据库中添加特定时间的注释时安排通知.虽然有多种方法可以使用AlarmManager,BroadcastReceiver等.如何使用WorkManager完成?
因为OneTimeWorkRequest
,我们可以setInitialDelay
具体说明最初的延迟.
但是,没有这样的设施PeriodicWorkRequest
.
有没有可靠的方法来实现这一目标?
一种不太可靠的方法,就是让一个延迟OneTimeWorkRequest
工人,进行设置PeriodicWorkRequest
.然而,这非常麻烦,并且创造了一种可能性,OneTimeWorkRequest
可能会失败并且无法安装PeriodicWorkRequest
.
如何检查是否WorkManager
已安排.
这是我安排的代码WorkManager
.
public static void scheduleWork() {
PeriodicWorkRequest.Builder photoCheckBuilder =
new PeriodicWorkRequest.Builder(WorkManagerService.class, TIME_INTERVAL_IN_SECONDS,
TimeUnit.SECONDS);
PeriodicWorkRequest photoCheckWork = photoCheckBuilder.build();
WorkManager instance = WorkManager.getInstance();
if (instance != null) {
instance.enqueueUniquePeriodicWork("TAG", ExistingPeriodicWorkPolicy.KEEP , photoCheckWork);
}
}
Run Code Online (Sandbox Code Playgroud)
我把scheduleWork()
在onCreate()
我的Application
课.即使我可以通过这种方法检查我的服务是否正在运行.但我不希望安排WorkManager,如果它已经安排在计划时间内删除不一致.
喜欢
if(!workManagerIsScheduled())
{
scheduleWork();
}
Run Code Online (Sandbox Code Playgroud)
有解决方案吗
没有任何官方文档(至少我已经阅读了文档)来解释这两种模式背后的用法和机制。它们是如何工作的?他们解决了什么问题?
如果有人可以为我简化它,我将不胜感激,因为我已经测试了两者并且没有看到任何有趣的事情。如果你问我,我会说不OneTimeWorkRequest.setBackoffCriteria()
影响工作。
这是我的代码,
@Override
public void doSomethingUseful(String order) {
Constraints constraint = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
Data data = new Data.Builder()
.putString("order", order)
.build();
OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(OrderSenderWorker.class)
.setConstraints(constraint)
.setInputData(data)
.setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 15, TimeUnit.SECONDS)
.build();
WorkManager.getInstance().beginUniqueWork("refresh-order", ExistingWorkPolicy.REPLACE, oneTimeWorkRequest).enqueue();
}
Run Code Online (Sandbox Code Playgroud)
在Worker
课堂上,每当我出错时,我都会WorkerResult.RETRY
在doWork()
方法中返回。
提前致谢 。