Android WorkManager与JobScheduler

Nik*_*nko 27 android android-jobscheduler android-workmanager

如果我们已经有一个JobScheduler以及一些具有相同功能的漂亮的后端(AndroidJobFirebaseJobDispatcher),为什么我们需要新的Android WorkManager?它有任何杀戮功能吗?因为我没有看到任何让我想要迁移到另一个调度程序的东西.

Nik*_*nko 31

"WorkManager有很多不错的功能,但它的主要目标是在旧设备上使用JobScheduler的API"......等等,但我们已经有了一些反向移植.他们怎么了?缩短它:

  1. FireaseJobDispatcher很好,但是如果我们以中国为目标,它需要Google Play来安排好的工作.

  2. 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支持.所以我的上一个问题的答案是肯定的,它确实有一些杀戮功能:

  • 无需Google Play
  • 可查询
  • 可链接
  • 机会主义的

要了解有关WorkManager的更多信息,请务必观看Sumir Kataria的演讲

PS如果有人知道为什么FirebaseJobDispatcher 得到Google工程师的积极支持而不是被弃用,请在下面的评论中写:)

  • FirebaseJobDispatcher 现已弃用,请参阅此处的自述文件 - https://github.com/firebase/firebase-jobdispatcher-android (8认同)

Emm*_*ali 16

首先,WorkManager用于可以延期并需要保证执行的工作。考虑到向后兼容性JobScheduler仅适用于 API 23+。为了避免必须处理向后兼容性,WorkManager 会为您执行以下操作:-

在此处输入图片说明

工作经理的特点

  • 有保证的约束感知执行
  • 尊重系统后台限制
  • Quarreable,您可以检查状态,即失败、成功等
  • 可链接,例如工作-A 取决于工作-B -> 工作图
  • 机会主义,尽量在满足约束后尽快执行,而实际上不需要作业调度程序进行干预,即唤醒应用程序或等待JobSheduler批处理您的工作,如果您的进程启动并运行
  • 向后兼容,有或没有 google play 服务

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可能是值得的.


Mic*_*sky 6

在我的测试中,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)


Arn*_*Rao 5

WorkManager使用JobScheduler服务来安排作业。如果JobScheduler设备不支持,则它将使用Firebase JobDispatcher服务。如果Firebase JobDispatcher在设备上不可用,它将使用AlarmManagerBroadcastReceiver

因此,有了WorkManager,您无需担心向后兼容性。除此之外,它还允许定义一些约束条件,例如,定义网络约束条件,电池电量,充电状态和存储电量,这些约束条件才能使作业运行。

它允许任务链和参数传递给工作。

http://www.zoftino.com/scheduling-tasks-with-workmanager-in-android


归档时间:

查看次数:

11849 次

最近记录:

5 年,12 月 前