我正在开发一个必须定期执行同步任务的应用程序。我使用了AlarmManager和BroadcastReceiver的组合来计划任务。但是,代码变得越来越复杂且难以维护,因为我必须处理网络问题,重新启动操作和电池状态,然后在必要时(并且当它已经完成时)再次安排任务,然后我发现WorkManager已经为我照顾那些事情。
我遇到>> this topic <<中描述的类似问题(WorkManager不重复PeriodicWorkRequest),该任务在初始时间间隔后被触发,但不再重复。但是,我已经在使用“稳定版本”,该版本应该可以正常运行。
好吧,这是gradle依赖项:
dependencies {
def work_version = "2.2.0"
implementation "androidx.work:work-runtime:$work_version"
androidTestImplementation "androidx.work:work-testing:$work_version"
}
Worker(我包括了一些“ writeToFile”调用,因此我可以调试是否调用了Worker和Service):
package com.nintersoft.bibliotecaufabc.synchronization;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import com.nintersoft.bibliotecaufabc.R;
import com.nintersoft.bibliotecaufabc.utilities.GlobalFunctions;
public class SyncManager extends Worker {
private Long lastSync;
private Context mContext;
public SyncManager(@NonNull Context context, WorkerParameters params){
super(context, params);
mContext = context;
}
@NonNull
@Override
@SuppressWarnings("StatementWithEmptyBody")
public Result doWork() {
//_DEBUG: Remove function call and scope
GlobalFunctions.writeToFile("__REQUESTED!", "request-manager");
// Acquires last sync time
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(mContext);
lastSync = pref.getLong(mContext.getString(R.string.key_synchronization_schedule), System.currentTimeMillis());
// Starts SyncService
ContextCompat.startForegroundService(mContext, new Intent(mContext, SyncService.class));
// Waits for completion
while (isServiceRunning());
// Checks whether the sync was successful or not
return isSyncComplete() ? Result.success() : Result.retry();
}
private boolean isServiceRunning(){
ActivityManager aManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
if (aManager != null)
for (ActivityManager.RunningServiceInfo service : aManager.getRunningServices(Integer.MAX_VALUE))
if (SyncService.class.getName().equals(service.service.getClassName())) return true;
return false;
}
private boolean isSyncComplete(){
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(mContext);
Long cLastSync = pref.getLong(mContext.getString(R.string.key_synchronization_schedule), System.currentTimeMillis());
return cLastSync > lastSync;
}
}
这是我设置详细信息的地方(请注意,存在一些建议性问题,因此我可以对其进行正确调试)。
private void setSyncSchedule(){
SharedPreferences prefs;
// TODO: Remove "or true" from conditional
//noinspection ConstantConditions,PointlessBooleanExpression
if ((prefs = PreferenceManager.getDefaultSharedPreferences(this))
.getBoolean(getString(R.string.key_app_first_run), true)
|| true){
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresBatteryNotLow(true)
.build();
// FIXME: Change to scheduled days again
PeriodicWorkRequest syncRequest = new PeriodicWorkRequest.Builder(SyncManager.class,
//GlobalVariables.syncInterval, TimeUnit.DAYS)
17, TimeUnit.MINUTES, 6, TimeUnit.MINUTES)
.setInitialDelay(1, TimeUnit.MINUTES)
.setConstraints(constraints)
.addTag(GlobalConstants.SYNC_WORK_TAG)
.build();
WorkManager workManager = WorkManager.getInstance(getApplicationContext());
workManager.cancelUniqueWork(GlobalConstants.SYNC_WORK_TAG);
workManager.pruneWork();
//workManager.enqueue(syncRequest);
workManager.enqueueUniquePeriodicWork(GlobalConstants.SYNC_WORK_TAG,
ExistingPeriodicWorkPolicy.KEEP, syncRequest);
// TODO: Change evocation to this one?
//WorkManager.getInstance(this).enqueueUniquePeriodicWork(GlobalConstants.SYNC_WORK_TAG,
//ExistingPeriodicWorkPolicy.KEEP, syncRequest);
prefs.edit()
.putBoolean(getString(R.string.key_app_first_run), false)
.apply();
}
}
好了,如您所见,我已经安排了一个PeriodicWorkRequest为16分钟(我想确保它大于最小间隔(即15))。
我已经尝试过的一些不同的事情:
以下是一些有关我在其中进行测试的设备的有用信息: