Nik*_*nko 27 android android-jobscheduler android-workmanager
如果我们已经有一个JobScheduler以及一些具有相同功能的漂亮的后端(AndroidJob和FirebaseJobDispatcher),为什么我们需要新的Android WorkManager?它有任何杀戮功能吗?因为我没有看到任何让我想要迁移到另一个调度程序的东西.
Nik*_*nko 31
"WorkManager有很多不错的功能,但它的主要目标是在旧设备上使用JobScheduler的API"......等等,但我们已经有了一些反向移植.他们怎么了?缩短它:
FireaseJobDispatcher很好,但是如果我们以中国为目标,它需要Google Play来安排好的工作.
Evernote的AndroidJob是一款出色的后端,具有很多功能.Imho,这是安排任何工作的最佳选择.但是现在该库的最新版本使用了前面提到的WorkManager.不幸的是,图书馆迟早会被弃用:
如果启动新项目,则应使用WorkManager而不是此库.您还应该开始将代码从此库迁移到WorkManager.在将来的某个时候,这个库将被弃用.
他们建议切换到WorkManager,因为它提供了更多的功能,它们也给我们一个简短的比较:
| Feature | android-job | WorkManager |
| ------------------ | ----------- | ----------- |
| Exact jobs | Yes | No |
| Transient jobs | Yes | No |
| Daily jobs | Yes | No |
| Custom Logger | Yes | No |
| Observe job status | No | Yes |
| Chained jobs | No | Yes |
| Work sequences | No | Yes |
Run Code Online (Sandbox Code Playgroud)
Imo,最后3个功能非常有用,仅由WorkManager支持.所以我的上一个问题的答案是肯定的,它确实有一些杀戮功能:
要了解有关WorkManager的更多信息,请务必观看Sumir Kataria的演讲
PS如果有人知道为什么FirebaseJobDispatcher 得到Google工程师的积极支持而不是被弃用,请在下面的评论中写:)
Emm*_*ali 16
首先,WorkManager用于可以延期并需要保证执行的工作。考虑到向后兼容性JobScheduler仅适用于 API 23+。为了避免必须处理向后兼容性,WorkManager 会为您执行以下操作:-
工作经理的特点
JobSheduler批处理您的工作,如果您的进程启动并运行WorkManager 提供 API 级别 14 的兼容性。WorkManager 根据设备 API 级别选择合适的方式来安排后台任务。它可能使用 JobScheduler(在 API 23 及更高版本上)或 AlarmManager 和 BroadcastReceiver 的组合
引擎盖下的扩展架构
Ste*_*etz 12
WorkManager似乎是Google对Evernote的Android-Job库的回答,但有一些改进.它使用JobScheduler,Firebase JobDispatcher和AlarmManager,就像Android-Job一样,具体取决于设备的API级别.他们对标签的使用看起来几乎相同,并且为作业/工作分配约束也足够相似.
我很兴奋的两个特点是:能够将工作链接起来,并且能够在有约束力的情况下投入工作机会.第一个将允许工作(工作)分解,并为我更模块化.通过更多的模块化工作,每项工作可能会有更少的约束,从而提高他们提前完成的机会(机会主义).例如,大多数处理工作可以在需要满足网络约束的工作之前完成.
因此,如果您对当前的调度程序实现感到满意,并且我提到的这两个功能没有增加价值,那么我认为尚未实现切换的巨大好处.但如果您正在撰写新内容,那么使用WorkManager可能是值得的.
在我的测试中,JobScheduler 可以在用户关闭我的应用程序后继续运行服务,但我找不到使用 WorkManager 执行此操作的方法。
我在运行 Oreo Android 8.0.0 (API 26) 的 Nexus 5X 上进行了测试。我可能只是很幸运,该设备/操作系统组合可以在终止应用程序后继续提供服务。我相信它可能是特定于设备的,因为我在这个答案/sf/answers/3682385241/中读到了Android 的内容。应用程序关闭时 WorkManager 是否正在运行?。“您可以在dontkillmyapp.com上找到不同 OEM 行为的完整列表。”
注意:我观察到,当用户关闭应用程序时,JobService 需要几秒钟甚至几分钟的时间才能重新启动。
为了使 JobScheduler 启动一个在应用程序死亡后仍然存在的服务,请按如下方式创建该服务:
JobScheduler jobScheduler = (JobScheduler)applicationContext.getSystemService(Context.JOB_SCHEDULER_SERVICE);
ComponentName componentName = new ComponentName(applicationContext, ScannerAsJobService.class);
JobInfo jobInfo = new JobInfo.Builder(JOB_ID, componentName)
.setPersisted(true) // relaunch on reboot
.setMinimumLatency(1)
.setOverrideDeadline(1)
.build();
int result = jobScheduler.schedule(jobInfo);
Run Code Online (Sandbox Code Playgroud)
ScannerAsJobService使用当前信息更新通知,包括服务是否“在后台”(我引用它是因为“后台”有不同的定义,但这个准确地反映了应用程序是否不再运行):
import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Handler;
import androidx.annotation.RequiresApi;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class ScannerAsJobService extends JobService {
private static final String TAG = "ScannerAsJobService";
private static final String NOTIFICATION_CHANNEL_ID = "ll_notification_channel";
final Handler workHandler = new Handler();
Runnable workRunnable;
@Override
public boolean onStartJob(JobParameters params) {
workRunnable = new Runnable() {
@Override
public void run() {
// See /sf/ask/3198452701/
(new Timer()).schedule(new TimerTask() {
@Override
public void run() {
String message = "Time: " + (new Date()).toString() + " background: " + appIsInBackground();
// /sf/answers/2264237251/
Intent intent = new Intent();
PendingIntent pendingIntent = PendingIntent.getActivity(ScannerAsJobService.this, 1, intent, 0);
Notification.Builder builder = new Notification.Builder(ScannerAsJobService.this);
builder.setAutoCancel(false);
builder.setTicker("my ticker info");
builder.setContentTitle("my content title");
builder.setContentText(message);
builder.setSmallIcon(R.drawable.my_icon);
builder.setContentIntent(pendingIntent);
// builder.setOngoing(true); // optionally uncomment this to prevent the user from being able to swipe away the notification
builder.setSubText("my subtext"); //API level 16
builder.setNumber(100);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setupNotificationChannel(NOTIFICATION_CHANNEL_ID);
builder.setChannelId(NOTIFICATION_CHANNEL_ID);
}
builder.build();
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.notify(93423, builder.build());
Log.d(TAG + " Notification message: " + message);
}
}, 1 * 1000, 5 * 1000);
jobFinished(params, true);
}
};
workHandler.post(workRunnable);
// return true so Android knows the workRunnable is continuing in the background
return true;
}
// /sf/answers/3198454171/
@RequiresApi(api = Build.VERSION_CODES.O)
private void setupNotificationChannel(String channelId) {
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// The user-visible name of the channel.
CharSequence name = getString(R.string.my_channel_name);
// The user-visible description of the channel.
String description = getString(R.string.my_channel_name);
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel mChannel = new NotificationChannel(channelId, name, importance);
// Configure the notification channel.
mChannel.setDescription(description);
mChannel.enableLights(true);
// Sets the notification light color for notifications posted to this
// channel, if the device supports this feature.
mChannel.setLightColor(Color.RED);
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
mNotificationManager.createNotificationChannel(mChannel);
}
/**
* Source: <a href="/sf/answers/2771240461/">/sf/answers/2771240461/</a>
* @return true if the app is in the background, false otherwise
*/
private boolean appIsInBackground() {
ActivityManager.RunningAppProcessInfo myProcess = new ActivityManager.RunningAppProcessInfo();
ActivityManager.getMyMemoryState(myProcess);
boolean isInBackground = myProcess.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
return isInBackground;
}
@Override
public boolean onStopJob(JobParameters params) {
// returning true schedules the job for retry (we're using it to implement periodicity since
// JobInfo.Builder.setPeriodic() didn't work
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
WorkManager使用JobScheduler服务来安排作业。如果JobScheduler设备不支持,则它将使用Firebase JobDispatcher服务。如果Firebase JobDispatcher在设备上不可用,它将使用AlarmManager和BroadcastReceiver。
因此,有了WorkManager,您无需担心向后兼容性。除此之外,它还允许定义一些约束条件,例如,定义网络约束条件,电池电量,充电状态和存储电量,这些约束条件才能使作业运行。
它允许任务链和参数传递给工作。
http://www.zoftino.com/scheduling-tasks-with-workmanager-in-android
| 归档时间: |
|
| 查看次数: |
11849 次 |
| 最近记录: |