Browse Source

Merge pull request #649 from bwitt/switch-to-work-manager

Switch to work manager
pull/648/head
Eric Kok 12 months ago committed by GitHub
parent
commit
0abe266146
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      README.md
  2. 2
      app/build.gradle
  3. 12
      app/src/main/AndroidManifest.xml
  4. 22
      app/src/main/java/org/transdroid/core/gui/TransdroidApp.java
  5. 49
      app/src/main/java/org/transdroid/core/service/AppUpdateJob.java
  6. 17
      app/src/main/java/org/transdroid/core/service/AppUpdateJobRunner.java
  7. 45
      app/src/main/java/org/transdroid/core/service/RssCheckerJob.java
  8. 11
      app/src/main/java/org/transdroid/core/service/RssCheckerJobRunner.java
  9. 42
      app/src/main/java/org/transdroid/core/service/ScheduledJobCreator.java
  10. 45
      app/src/main/java/org/transdroid/core/service/ServerCheckerJob.java
  11. 8
      app/src/main/java/org/transdroid/core/service/ServerCheckerJobRunner.java

3
README.md

@ -108,9 +108,6 @@ Some code/libraries/resources are used in the project:
* [Material Dialogs](https://github.com/afollestad/material-dialogs) * [Material Dialogs](https://github.com/afollestad/material-dialogs)
Aidan Follestad Aidan Follestad
Apache License, Version 2.0 Apache License, Version 2.0
* [Android-Job](https://github.com/evernote/android-job)
Evernote Corporation
Apache License, Version 2.0
* [android-ColorPickerPreference](https://github.com/attenzione/android-ColorPickerPreference) * [android-ColorPickerPreference](https://github.com/attenzione/android-ColorPickerPreference)
Daniel Nilsson and Sergey Margaritov Daniel Nilsson and Sergey Margaritov
Apache License, Version 2.0 Apache License, Version 2.0

2
app/build.gradle

@ -97,7 +97,7 @@ dependencies {
implementation('com.github.afollestad.material-dialogs:core:0.9.6.0@aar') { implementation('com.github.afollestad.material-dialogs:core:0.9.6.0@aar') {
transitive = true transitive = true
} }
implementation 'com.evernote:android-job:1.4.3' implementation 'androidx.work:work-runtime:2.7.1'
implementation "androidx.lifecycle:lifecycle-viewmodel:2.5.1" implementation "androidx.lifecycle:lifecycle-viewmodel:2.5.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"

12
app/src/main/AndroidManifest.xml

@ -273,6 +273,18 @@
android:authorities="@string/search_history_authority" android:authorities="@string/search_history_authority"
android:exported="false" /> android:exported="false" />
<!-- allow debug logs for WorkManager -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
<!-- RSS --> <!-- RSS -->
<activity <activity
android:name="org.transdroid.core.gui.rss.RssFeedsActivity_" android:name="org.transdroid.core.gui.rss.RssFeedsActivity_"

22
app/src/main/java/org/transdroid/core/gui/TransdroidApp.java

@ -18,27 +18,21 @@ package org.transdroid.core.gui;
import android.app.Application; import android.app.Application;
import com.evernote.android.job.JobConfig; import androidx.annotation.NonNull;
import com.evernote.android.job.JobManager; import androidx.work.Configuration;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EApplication; import org.androidannotations.annotations.EApplication;
import org.transdroid.core.gui.log.Log; import org.transdroid.core.gui.log.Log;
import org.transdroid.core.service.ScheduledJobCreator;
@EApplication @EApplication
public class TransdroidApp extends Application { public class TransdroidApp extends Application implements Configuration.Provider {
@Bean
protected Log log;
@NonNull
@Override @Override
public void onCreate() { public Configuration getWorkManagerConfiguration() {
super.onCreate(); return new Configuration.Builder()
.setMinimumLoggingLevel(android.util.Log.DEBUG)
// Configure Android-Job .build();
JobConfig.addLogger((priority, tag, message, t) -> log.d(tag, message));
JobManager.create(this).addJobCreator(new ScheduledJobCreator());
} }
} }

49
app/src/main/java/org/transdroid/core/service/AppUpdateJob.java

@ -16,13 +16,19 @@
*/ */
package org.transdroid.core.service; package org.transdroid.core.service;
import static java.security.AccessController.getContext;
import android.content.Context; import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.evernote.android.job.Job; import androidx.work.Constraints;
import com.evernote.android.job.JobManager; import androidx.work.Operation;
import com.evernote.android.job.JobRequest; import androidx.work.PeriodicWorkRequest;
import androidx.work.Worker;
import androidx.work.WorkManager;
import androidx.work.NetworkType;
import androidx.work.WorkerParameters;
import org.transdroid.core.app.settings.NotificationSettings; import org.transdroid.core.app.settings.NotificationSettings;
import org.transdroid.core.app.settings.NotificationSettings_; import org.transdroid.core.app.settings.NotificationSettings_;
@ -31,37 +37,48 @@ import org.transdroid.core.app.settings.SystemSettings_;
import org.transdroid.core.gui.log.Log_; import org.transdroid.core.gui.log.Log_;
import org.transdroid.core.gui.navigation.NavigationHelper_; import org.transdroid.core.gui.navigation.NavigationHelper_;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class AppUpdateJob extends Job { public class AppUpdateJob extends Worker {
static final String TAG = "app_update_checker"; static final String TAG = "app_update_checker";
private static Integer scheduledJobId; private static UUID scheduledJobId;
public AppUpdateJob(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
public static void schedule(Context context) { public static <SimpleJob> void schedule(Context context) {
NotificationSettings notificationSettings = NotificationSettings_.getInstance_(context); NotificationSettings notificationSettings = NotificationSettings_.getInstance_(context);
SystemSettings systemSettings = SystemSettings_.getInstance_(context); SystemSettings systemSettings = SystemSettings_.getInstance_(context);
NavigationHelper_ navigationHelper = NavigationHelper_.getInstance_(context); NavigationHelper_ navigationHelper = NavigationHelper_.getInstance_(context);
if (systemSettings.checkForUpdates() && navigationHelper.enableUpdateChecker()) { if (systemSettings.checkForUpdates() && navigationHelper.enableUpdateChecker()) {
Log_.getInstance_(context).d(TAG, "Schedule app update checker job"); Log_.getInstance_(context).d(TAG, "Schedule app update checker job");
NotificationChannels.ensureAppUpdateChannel(context, notificationSettings); NotificationChannels.ensureAppUpdateChannel(context, notificationSettings);
scheduledJobId = new JobRequest.Builder(AppUpdateJob.TAG) Constraints constraints = new Constraints.Builder()
.setPeriodic(TimeUnit.DAYS.toMillis(1)) .setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED) .build();
.setUpdateCurrent(true) PeriodicWorkRequest appUpdate = new PeriodicWorkRequest.Builder(AppUpdateJob.class, 1, TimeUnit.DAYS)
.build() .addTag(AppUpdateJob.TAG)
.schedule(); .setConstraints(constraints)
.build();
WorkManager.getInstance(context).cancelAllWorkByTag(AppUpdateJob.TAG);
WorkManager.getInstance(context).enqueue(appUpdate);
scheduledJobId = appUpdate.getId();
} else if (scheduledJobId != null) { } else if (scheduledJobId != null) {
Log_.getInstance_(context).d(TAG, "Cancel rss checker job"); Log_.getInstance_(context).d(TAG, "Cancel app update checker job");
JobManager.instance().cancel(scheduledJobId); WorkManager.getInstance(context).cancelWorkById(scheduledJobId);
scheduledJobId = null;
} }
} }
@NonNull @NonNull
@Override @Override
protected Result onRunJob(@NonNull Params params) { public Result doWork() {
return AppUpdateJobRunner_.getInstance_(getContext()).run(); return AppUpdateJobRunner_.getInstance_(getApplicationContext()).run();
} }
} }

17
app/src/main/java/org/transdroid/core/service/AppUpdateJobRunner.java

@ -26,7 +26,8 @@ import android.net.Uri;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import com.evernote.android.job.Job; import androidx.work.ListenableWorker;
import androidx.work.Worker;
import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EBean; import org.androidannotations.annotations.EBean;
@ -73,16 +74,16 @@ public class AppUpdateJobRunner {
@SystemService @SystemService
protected NotificationManager notificationManager; protected NotificationManager notificationManager;
Job.Result run() { Worker.Result run() {
// Only run this service if app updates are handled via transdroid.org at all // Only run this service if app updates are handled via transdroid.org at all
if (!navigationHelper.enableUpdateChecker()) if (!navigationHelper.enableUpdateChecker())
return Job.Result.FAILURE; return Worker.Result.failure();
if (!connectivityHelper.shouldPerformBackgroundActions() || !systemSettings.checkForUpdates()) { if (!connectivityHelper.shouldPerformBackgroundActions() || !systemSettings.checkForUpdates()) {
log.d(this, "Skip the app update service, as background data is disabled, the service is explicitly " + log.d(this, "Skip the app update service, as background data is disabled, the service is explicitly " +
"disabled or we are not connected."); "disabled or we are not connected.");
return Job.Result.RESCHEDULE; return Worker.Result.retry();
} }
Date lastChecked = systemSettings.getLastCheckedForAppUpdates(); Date lastChecked = systemSettings.getLastCheckedForAppUpdates();
@ -91,7 +92,7 @@ public class AppUpdateJobRunner {
if (lastChecked != null && lastChecked.after(lastDay.getTime())) { if (lastChecked != null && lastChecked.after(lastDay.getTime())) {
log.d(this, "Skip the update service, as we already checked the last 24 hours (or to be exact at " log.d(this, "Skip the update service, as we already checked the last 24 hours (or to be exact at "
+ lastChecked.toString() + ")."); + lastChecked.toString() + ").");
return Job.Result.RESCHEDULE; return Worker.Result.retry();
} }
DefaultHttpClient httpclient = new DefaultHttpClient(); DefaultHttpClient httpclient = new DefaultHttpClient();
@ -124,7 +125,7 @@ public class AppUpdateJobRunner {
// New version of the search module? // New version of the search module?
try { try {
PackageInfo searchPackage = context.getPackageManager().getPackageInfo("org.transdroid.search", 0); PackageInfo searchPackage = context.getPackageManager().getPackageInfo("org.transdroid.search", 0);
log.d(this, "Local Transdroid Seach is at " + searchPackage.getLongVersionCode() log.d(this, "Local Transdroid Search is at " + searchPackage.getLongVersionCode()
+ " and the reported latest version is " + searchVersion); + " and the reported latest version is " + searchVersion);
if (searchPackage.getLongVersionCode() < searchVersion) { if (searchPackage.getLongVersionCode() < searchVersion) {
// New version available! Notify the user. // New version available! Notify the user.
@ -145,10 +146,10 @@ public class AppUpdateJobRunner {
} catch (Exception e) { } catch (Exception e) {
// Cannot check right now for some reason; log and ignore // Cannot check right now for some reason; log and ignore
log.d(this, "Cannot retrieve latest app or search module version code from the site: " + e.toString()); log.d(this, "Cannot retrieve latest app or search module version code from the site: " + e.toString());
return Job.Result.FAILURE; return Worker.Result.failure();
} }
return Job.Result.SUCCESS; return Worker.Result.success();
} }
/** /**

45
app/src/main/java/org/transdroid/core/service/RssCheckerJob.java

@ -16,45 +16,62 @@
*/ */
package org.transdroid.core.service; package org.transdroid.core.service;
import static java.security.AccessController.getContext;
import android.content.Context; import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.evernote.android.job.Job; import androidx.work.Constraints;
import com.evernote.android.job.JobManager; import androidx.work.PeriodicWorkRequest;
import com.evernote.android.job.JobRequest; import androidx.work.Worker;
import androidx.work.WorkManager;
import androidx.work.NetworkType;
import androidx.work.WorkerParameters;
import org.transdroid.core.app.settings.NotificationSettings; import org.transdroid.core.app.settings.NotificationSettings;
import org.transdroid.core.app.settings.NotificationSettings_; import org.transdroid.core.app.settings.NotificationSettings_;
import org.transdroid.core.gui.log.Log_; import org.transdroid.core.gui.log.Log_;
public class RssCheckerJob extends Job { import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class RssCheckerJob extends Worker {
static final String TAG = "rss_checker"; static final String TAG = "rss_checker";
private static Integer scheduledJobId; private static UUID scheduledJobId;
public RssCheckerJob(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
public static void schedule(Context context) { public static void schedule(Context context) {
NotificationSettings notificationSettings = NotificationSettings_.getInstance_(context); NotificationSettings notificationSettings = NotificationSettings_.getInstance_(context);
if (notificationSettings.isEnabledForRss()) { if (notificationSettings.isEnabledForRss()) {
Log_.getInstance_(context).d(TAG, "Schedule rss checker job"); Log_.getInstance_(context).d(TAG, "Schedule rss checker job");
NotificationChannels.ensureRssCheckerChannel(context, notificationSettings); NotificationChannels.ensureRssCheckerChannel(context, notificationSettings);
scheduledJobId = new JobRequest.Builder(RssCheckerJob.TAG) Constraints constraints = new Constraints.Builder()
.setPeriodic(notificationSettings.getInvervalInMilliseconds()) .setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED) .build();
.setUpdateCurrent(true) PeriodicWorkRequest rssChecker = new PeriodicWorkRequest.Builder(RssCheckerJob.class, notificationSettings.getInvervalInMilliseconds(), TimeUnit.MILLISECONDS)
.build() .addTag(RssCheckerJob.TAG)
.schedule(); .setConstraints(constraints)
.build();
WorkManager.getInstance(context).cancelAllWorkByTag(RssCheckerJob.TAG);
WorkManager.getInstance(context).enqueue(rssChecker);
scheduledJobId = rssChecker.getId();
} else if (scheduledJobId != null) { } else if (scheduledJobId != null) {
Log_.getInstance_(context).d(TAG, "Cancel rss checker job"); Log_.getInstance_(context).d(TAG, "Cancel rss checker job");
JobManager.instance().cancel(scheduledJobId); WorkManager.getInstance(context).cancelWorkById(scheduledJobId);
scheduledJobId = null;
} }
} }
@NonNull @NonNull
@Override @Override
protected Result onRunJob(@NonNull Params params) { public Result doWork() {
return RssCheckerJobRunner_.getInstance_(getContext()).run(); return RssCheckerJobRunner_.getInstance_(getApplicationContext()).run();
} }
} }

11
app/src/main/java/org/transdroid/core/service/RssCheckerJobRunner.java

@ -22,8 +22,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import androidx.work.Worker;
import com.evernote.android.job.Job;
import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EBean; import org.androidannotations.annotations.EBean;
@ -59,12 +58,12 @@ public class RssCheckerJobRunner {
@SystemService @SystemService
protected NotificationManager notificationManager; protected NotificationManager notificationManager;
Job.Result run() { Worker.Result run() {
if (!connectivityHelper.shouldPerformBackgroundActions() || !notificationSettings.isEnabledForRss()) { if (!connectivityHelper.shouldPerformBackgroundActions() || !notificationSettings.isEnabledForRss()) {
log.d(this, log.d(this,
"Skip the RSS checker service, as background data is disabled, the service is disabled or we are not connected."); "Skip the RSS checker service, as background data is disabled, the service is disabled or we are not connected.");
return Job.Result.RESCHEDULE; return Worker.Result.retry();
} }
// Check every RSS feed for new items // Check every RSS feed for new items
@ -117,7 +116,7 @@ public class RssCheckerJobRunner {
if (unread == 0) { if (unread == 0) {
// No new items; just exit // No new items; just exit
return Job.Result.SUCCESS; return Worker.Result.success();
} }
// Provide a notification, since there are new RSS items // Provide a notification, since there are new RSS items
@ -140,7 +139,7 @@ public class RssCheckerJobRunner {
} }
notificationManager.notify(80001, builder.build()); notificationManager.notify(80001, builder.build());
return Job.Result.SUCCESS; return Worker.Result.success();
} }
} }

42
app/src/main/java/org/transdroid/core/service/ScheduledJobCreator.java

@ -1,42 +0,0 @@
/*
* Copyright 2010-2018 Eric Kok et al.
*
* Transdroid is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Transdroid is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
*/
package org.transdroid.core.service;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.evernote.android.job.Job;
import com.evernote.android.job.JobCreator;
public class ScheduledJobCreator implements JobCreator {
@Nullable
@Override
public Job create(@NonNull String tag) {
switch (tag) {
case AppUpdateJob.TAG:
return new AppUpdateJob();
case RssCheckerJob.TAG:
return new RssCheckerJob();
case ServerCheckerJob.TAG:
return new ServerCheckerJob();
default:
return null;
}
}
}

45
app/src/main/java/org/transdroid/core/service/ServerCheckerJob.java

@ -20,41 +20,58 @@ import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.evernote.android.job.Job; import androidx.annotation.WorkerThread;
import com.evernote.android.job.JobManager; import androidx.work.Constraints;
import com.evernote.android.job.JobRequest; import androidx.work.PeriodicWorkRequest;
import androidx.work.Worker;
import androidx.work.WorkManager;
import androidx.work.NetworkType;
import androidx.work.WorkerParameters;
import org.transdroid.core.app.settings.NotificationSettings; import org.transdroid.core.app.settings.NotificationSettings;
import org.transdroid.core.app.settings.NotificationSettings_; import org.transdroid.core.app.settings.NotificationSettings_;
import org.transdroid.core.gui.log.Log_; import org.transdroid.core.gui.log.Log_;
public class ServerCheckerJob extends Job { import java.time.Period;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class ServerCheckerJob extends Worker {
static final String TAG = "server_checker"; static final String TAG = "server_checker";
private static Integer scheduledJobId; private static UUID scheduledJobId;
public ServerCheckerJob(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
public static void schedule(Context context) { public static void schedule(Context context) {
NotificationSettings notificationSettings = NotificationSettings_.getInstance_(context); NotificationSettings notificationSettings = NotificationSettings_.getInstance_(context);
if (notificationSettings.isEnabledForTorrents()) { if (notificationSettings.isEnabledForTorrents()) {
Log_.getInstance_(context).d(TAG, "Schedule server checker job"); Log_.getInstance_(context).d(TAG, "Schedule server checker job");
NotificationChannels.ensureServerCheckerChannel(context, notificationSettings); NotificationChannels.ensureServerCheckerChannel(context, notificationSettings);
scheduledJobId = new JobRequest.Builder(ServerCheckerJob.TAG) Constraints constraints = new Constraints.Builder()
.setPeriodic(notificationSettings.getInvervalInMilliseconds()) .setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED) .build();
.setUpdateCurrent(true) PeriodicWorkRequest serverChecker = new PeriodicWorkRequest.Builder(ServerCheckerJob.class, notificationSettings.getInvervalInMilliseconds(), TimeUnit.MILLISECONDS)
.build() .addTag(ServerCheckerJob.TAG)
.schedule(); .setConstraints(constraints)
.build();
WorkManager.getInstance(context).cancelAllWorkByTag(ServerCheckerJob.TAG);
WorkManager.getInstance(context).enqueue(serverChecker);
scheduledJobId = serverChecker.getId();
} else if (scheduledJobId != null) { } else if (scheduledJobId != null) {
Log_.getInstance_(context).d(TAG, "Cancel server checker job"); Log_.getInstance_(context).d(TAG, "Cancel server checker job");
JobManager.instance().cancel(scheduledJobId); WorkManager.getInstance(context).cancelWorkById(scheduledJobId);
scheduledJobId = null;
} }
} }
@NonNull @NonNull
@Override @Override
protected Result onRunJob(@NonNull Params params) { public Result doWork() {
return ServerCheckerJobRunner_.getInstance_(getContext()).run(); return ServerCheckerJobRunner_.getInstance_(getApplicationContext()).run();
} }
} }

8
app/src/main/java/org/transdroid/core/service/ServerCheckerJobRunner.java

@ -22,7 +22,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import com.evernote.android.job.Job; import androidx.work.Worker;
import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EBean; import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.RootContext; import org.androidannotations.annotations.RootContext;
@ -61,12 +61,12 @@ public class ServerCheckerJobRunner {
@SystemService @SystemService
protected NotificationManager notificationManager; protected NotificationManager notificationManager;
Job.Result run() { Worker.Result run() {
if (!connectivityHelper.shouldPerformBackgroundActions() || !notificationSettings.isEnabledForTorrents()) { if (!connectivityHelper.shouldPerformBackgroundActions() || !notificationSettings.isEnabledForTorrents()) {
log.d(this, log.d(this,
"Skip the server checker service, as background data is disabled, the service is disabled or we are not connected."); "Skip the server checker service, as background data is disabled, the service is disabled or we are not connected.");
return Job.Result.RESCHEDULE; return Worker.Result.retry();
} }
int notifyBase = 10000; int notifyBase = 10000;
@ -207,7 +207,7 @@ public class ServerCheckerJobRunner {
} }
return Job.Result.SUCCESS; return Worker.Result.success();
} }
private Boolean findLastDoneStat(JSONArray lastStats, Torrent torrent) { private Boolean findLastDoneStat(JSONArray lastStats, Torrent torrent) {

Loading…
Cancel
Save