我正在研究 MVVM 架构,并使用 Dagger2 进行数据注入。我面临的问题是,在 Activity/Fragments 中,@Inject 工作正常,但在 WorkManager 的 Worker 类中,@Inject 在运行时给出空指针异常。我该如何解决它?
以下是Worker类代码:
public class MySyncManager extends Worker {
@Inject
DataManager dataManager;
@Inject
SchedulerProvider schedulerProvider;
@NonNull
@Override
public WorkerResult doWork() {
CommonUtils.Log("usm_work_manager_1", "Work is Started.");
if(dataManager==null)
CommonUtils.Log("usm_work_manager", "Injector is NULL");
}
}
Run Code Online (Sandbox Code Playgroud)
方法:
private void startTestSyncRequest() {
Constraints myConstraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(MySyncManager.class)
.setConstraints(myConstraints)
.setInitialDelay(1, TimeUnit.SECONDS) // wait for n seconds before starting service
.build();
WorkManager.getInstance()
.beginUniqueWork(Tags.TEST_WORK_NAME, ExistingWorkPolicy.REPLACE, workRequest)
.enqueue();
}
Run Code Online (Sandbox Code Playgroud) 如何在 Dagger 2.16 中为工人类实现 Dagger?
public class SyncWorker extends Worker {
@Inject
ISettingRepository settingRepository;
@NonNull
@Override
public Result doWork() {
sync();
return Result.SUCCESS;
}
private void sync() {
}
}
Run Code Online (Sandbox Code Playgroud)
我的应用程序组件
@Singleton
@Component(modules = {
AndroidSupportInjectionModule.class,
BaseModule.class,
ApiModule.class,
UserDatabaseModule.class,
SaleDatabaseModule.class,
AppModule.class,
ActivityBuilderModule.class
})
public interface AppComponent extends AndroidInjector<DaggerApplication> {
void inject(BaseApp app);
@Override
void inject(DaggerApplication application);
@Component.Builder
interface Builder {
@BindsInstance
Builder getApp(Application application);
AppComponent build();
}
}
Run Code Online (Sandbox Code Playgroud)
如何注入settingRepository?
java android dependency-injection dagger-2 android-workmanager
我试图观察我的workers但他们总是处于queued状态或有时它'sRUNNING但从来没有SUCCEED或FAILED。
是workStatus.state来自 returndoWork()还是不同?
这是我的工作脚本:
\n\npackage com.mockie.daikokuten.sync.workers\n\nimport androidx.work.Worker\n\n\nclass TestWorker:Worker()\n{\n\noverride fun doWork():Worker.Result\n{\n return Worker.Result.SUCCESS\n}\n\n}\nRun Code Online (Sandbox Code Playgroud)\n\n这是观察工人的脚本:
\n\n val test = PeriodicWorkRequest.Builder(\n TestWorker::class.java,\n PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS,\n TimeUnit.MILLISECONDS)\n .addTag("test_worker")\n .build()\n\n WorkManager.getInstance()?.enqueueUniquePeriodicWork("test_worker", ExistingPeriodicWorkPolicy.KEEP, test)\n\n WorkManager.getInstance()!!.getStatusesByTag("test_worker")\n .observe(this, Observer { workStatus ->\n if (workStatus != null)\n {\n for(ws in workStatus)\n {\n Log.d(":dump2 id ", ws.id.toString())\n Log.d(":dump2 tag", ws.tags.toString())\n Log.d(":dump2 state", ws.state.toString())\n }\n }\n })\nRun Code Online (Sandbox Code Playgroud)\n\n这是 Logcat 中的结果:
\n\n 07-23 17:12:30.901 29740-29740/com.mockie.daikokuten …Run Code Online (Sandbox Code Playgroud) 我目前使用 Firebase JobDipatcher 在后台执行周期性任务。问题是后台服务仅在禁用电池优化并且应用程序的待机状态在开发人员选项下手动设置为 ACTIVE 时才会执行。有没有办法在不手动更改所有这些的情况下完成后台任务,因为我不能要求应用程序的每个用户都这样做。并看到许多帖子说如果在应用程序中请求电源管理权限,谷歌将暂停该应用程序。任何帮助将非常感激。
android alarmmanager android-background firebase-job-dispatcher android-workmanager
我读到了工作管理器,它的文档说它在 API 23+ 的设备上使用 JobScheduler 并在 API 14-22 的设备上使用 BroadcastReceiver + AlarmManager 的组合,而 JobScheduler 可从 21 API 获得。那么为什么它不使用来自 21 API 的 JobScheduler。
我是第一次与工作经理合作,我已经成功地实施了它。
我每 30 分钟定位一次以跟踪员工。
我在数据库第一次同步时启动了我的工作管理器,但我想在每天晚上停止它。
这是MyWorker.java
public class MyWorker extends Worker {
private static final String TAG = "MyWorker";
/**
* The desired interval for location updates. Inexact. Updates may be more or less frequent.
*/
private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
/**
* The fastest rate for active location updates. Updates will never be more frequent
* than this value.
*/
private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
UPDATE_INTERVAL_IN_MILLISECONDS / 2;
/**
* The current location.
*/ …Run Code Online (Sandbox Code Playgroud) android location alarmmanager workmanagers android-workmanager
我阅读了这些说明:https : //developer.android.com/topic/libraries/architecture/workmanager/advanced/custom-configuration#on-demand 现在我有一个 MyApplication 类,但我不明白如何使用它和我在任何地方都找不到明确的说明
请求WorkManager.getInstance时,自然会产生错误,因为MyApplication类在任何地方都没有使用。我无法理解如何为 WorkManager 激活此类。
AndroidManifest.xml:
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove"
android:exported="false" />
Run Code Online (Sandbox Code Playgroud)
MyApplication.java:
public class MyApplication extends Application implements Configuration.Provider {
@NonNull
@Override
public Configuration getWorkManagerConfiguration() {
return new Configuration.Builder().
setExecutor(Executors.newFixedThreadPool(5)).build();
}
}
Run Code Online (Sandbox Code Playgroud)
我需要准确地解决这个问题,所以我会很感激你的好帮助。如何使按需初始化工作?
我将文件(由用户选择)排队上传,然后使用 WorkManager 更新同步状态,如下所示:
fun schedule(files: List<String>) {
var cont = workManager
.beginUniqueWork(issueId, APPEND, files.map { workRequest(it) })
.then(updateSyncStatusWork)
.enqueue()
}
Run Code Online (Sandbox Code Playgroud)
效果很好。但是,当用户选择大量文件并查看日志时,我发现很多文件正在同时上传(大约 10 个甚至全部)。并且发生了很多超时。我相信减少并行上传数量会减少超时次数,但我在 WorkManager 或 WorkRequest 中找不到任何允许这样做的 API。
PS 我不考虑链接它们,因为上传失败会删除其后所有文件的上传。
也许这是关于 WorkManager 的另一个问题,但我真的找不到解决方案......
正如标题所示,我正在尝试每 15 分钟运行一次定期工作。实际上,在工作人员中,我每分钟都会轮询一些数据。每次轮询后,几乎每隔 1 秒,我都会检查工作进程是否正在停止,如果是则返回,否则继续等待,直到达到 1 分钟并再次轮询数据。
根据文档,这应该有效,而且确实如此,直到我从最近的应用程序屏幕中杀死该应用程序。
这是代码:
package com.qsea.app.cordova;
import android.content.Context;
import android.os.SystemClock;
import android.util.Log;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
public class ServerListenerWorker extends Worker {
public static final String TAG = "ServerListenerWorker";
public ServerListenerWorker(
Context appContext,
WorkerParameters workerParams
) {
super(appContext, workerParams);
}
@Override
public Result doWork() {
Log.d(TAG, "Doing work");
final long startTime = SystemClock.elapsedRealtime();
final int maxDelta = 840000; // 14 minutes
while (true) {
// I did this to stop this worker …Run Code Online (Sandbox Code Playgroud) android background-service push-notification android-workmanager
我试图通过这种方式从 WorkManager 的挂起函数中获取结果
suspend fun uploadLogs(filePath: String): String {
val request = createRequest(createInputLogsData(filePath))
workManager.enqueue(request).await()
val url = workManager.getWorkInfoById(request.id).await().outputData.getString(KEY_URL)
return url
}
Run Code Online (Sandbox Code Playgroud)
但看起来await()函数不起作用。调用await()后,请求状态仍然处于ENQUEUED状态。
我需要在此协程上下文中从 WorkManager 同步获取结果。
也许我做错了什么?