我正在做一个样本项目来练习背景工作。首先,我用了firebasejobdispatcher,一切正常。。后来我知道了workmanager,这是目前做背景工作的最好方法。。
我的应用程序的想法是,用户输入他希望触发通知的分钟数,当使用firebasejobdispatcher时,通知会准时触发,但当我切换到workmanager时,通知会延迟近20秒+用户已经输入的时间。。换句话说,如果用户将触发器设置为1分钟,然后关闭应用程序,则在活动被销毁20秒后,倒计时再次开始。。这意味着通知将在1:20分钟后触发。
以下是mainactivity中的代码(使用workmanager):
Data data = new Data.Builder()
.putInt("number", minutes*60)
.build();
OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(MyWorker.class)
.setInputData(data)
.addTag("timer")
.build();
WorkManager.getInstance(MainActivity.this).enqueue(oneTimeWorkRequest);
mainactivity(使用firebasejobdispatcher)
JobSchedulerUtils.scheduleNotification(MainActivity.this, minutes);
以下是扩展worker的java类:
public class MyWorker extends Worker {
public MyWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@NonNull
@Override
/*
this is a simulation for background work, a countdown starts at a given number and this number decrements every second.
the process runs off of the main thread.
*/
public Result doWork() {
// this is like an intent bundle, if you want to pass data from the activity to the Worker
// in this app, the passed int is the number where we start countdown
Data inputData = getInputData();
int number = inputData.getInt("number", -1);
for(int i = number; i >= 0; i--){
Log.d("logmsg", i+"");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
return Result.failure();
}
}
TriggerTasks.executeTask(getApplicationContext(), TriggerTasks.TRIGGER_NOTIFICATION);
return Result.success();
}
}
以下是使用firebasejobdispatcher时使用的类:
a-schedulerfirebasejobdispatcher.java
public class SchedulerFirebaseJobService extends JobService {
private AsyncTask mTask;
@Override
public boolean onStartJob(final JobParameters job) {
mTask = new AsyncTask() {
@Override
protected Object doInBackground(Object[] objects) {
// work to be done in background
Context context = SchedulerFirebaseJobService.this;
TriggerTasks.executeTask(context, TriggerTasks.TRIGGER_NOTIFICATION);
return null;
}
@Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
jobFinished(job, false);
}
};
mTask.execute();
return true;
}
@Override
public boolean onStopJob(JobParameters job) {
if (mTask != null) mTask.cancel(true);
return false;
}
}
b-作业计划rutils.java
public class JobSchedulerUtils {
private static final String TRIGGER_NOTIFICATION_JOB_TAG = "trigger-notification";
synchronized public static void scheduleNotification(@NonNull final Context context, int time){
Driver driver = new GooglePlayDriver(context);
// TODO: use WorkManager instead of FirebaseJobDispatcher
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(driver);
// job is triggered in the service so we set service to SchedulerFirebaseJobService, but here we define the parameters of this job
// to be done in the background..
// in other words, services's doInBackground is triggered using the following parameters and after the event in setTrigger occurs
Job job = dispatcher.newJobBuilder().setService(SchedulerFirebaseJobService.class)
.setTag(TRIGGER_NOTIFICATION_JOB_TAG)
.setLifetime(Lifetime.FOREVER)
.setRecurring(false)
.setTrigger(Trigger.executionWindow(time*60, time*60))
.setReplaceCurrent(true)
.build();
dispatcher.schedule(job);
}
}
以下是两种情况下使用的其他类:
a-triggertasks.java
public class TriggerTasks {
public static final String DISMISS_NOTIFICATION = "dismiss-notification";
public static final String TRIGGER_NOTIFICATION = "trigger-notification";
public static void executeTask(Context context, String action){
if(DISMISS_NOTIFICATION.equals(action)){
NotificationUtils.clearAllNotifications(context);
}
if(TRIGGER_NOTIFICATION.equals(action)){
NotificationUtils.createNotification(context);
}
}
}
b-notificationutils.java
public class NotificationUtils {
private static final String NOTIFICATION_CHANNEL_ID = "notif-channel";
private static final String NOTIFICATION_CHANNEL_NAME = "Primary";
private static final int PENDING_INTENT_ID = 1991;
private static final int NOTIFICATION_ID = 500;
private static final int ACTION_IGNORE_PENDING_INTENT_ID = 24;
public static void clearAllNotifications(Context context){
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
}
public static void createNotification(Context context){
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
NotificationChannel notificationChannel = new NotificationChannel(
NOTIFICATION_CHANNEL_ID,
NOTIFICATION_CHANNEL_NAME,
NotificationManager.IMPORTANCE_HIGH
);
notificationManager.createNotificationChannel(notificationChannel);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(context,NOTIFICATION_CHANNEL_ID);
builder.setAutoCancel(true)
.setContentText(context.getString(R.string.notification_text))
.setContentTitle(context.getString(R.string.notification_title))
// this attribute controls what happens when a notification is clicked
.setContentIntent(contentIntent(context))
.setSmallIcon(R.drawable.ic_launcher_background)
.addAction(dismissNotification(context));
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
builder.setPriority(NotificationCompat.PRIORITY_HIGH);
}
notificationManager.notify(NOTIFICATION_ID, builder.build());
}
/*
guarantees that a click on the notification will start MainActivity
*/
private static PendingIntent contentIntent(Context context){
Intent toMainActivity = new Intent(context, MainActivity.class);
return PendingIntent.getActivity(
context,
PENDING_INTENT_ID,
toMainActivity,
PendingIntent.FLAG_UPDATE_CURRENT);
}
private static NotificationCompat.Action dismissNotification (Context context){
Intent intent = new Intent(context, TriggerIntentService.class);
intent.setAction(TriggerTasks.DISMISS_NOTIFICATION);
PendingIntent pendingIntent = PendingIntent.getService(
context,
ACTION_IGNORE_PENDING_INTENT_ID,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action dismissNotificationAction = new NotificationCompat.Action(
R.drawable.ic_launcher_foreground,
context.getString(R.string.notification_action_dismiss),
pendingIntent);
return dismissNotificationAction;
}
}
c-triggerintentservice.java
public class TriggerIntentService extends IntentService {
public TriggerIntentService() {
super("TriggerIntentService");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
String action = intent.getAction();
TriggerTasks.executeTask(this, action);
}
}
暂无答案!
目前还没有任何答案,快来回答吧!