未调用自定义 JobIntentService onHandleWork

Custom JobIntentService onHandleWork not called

我最近正在更新我正在使用 JobIntentService 而不是常规 IntentService 来处理来自推送的通知的应用程序,因为这似乎是在 Lollipop 之前处理此问题的正确方法设备以及 post。我正在排队工作:

enqueueWork(context, MyJobServiceExtension.class, JOB_ID, work);

这是清单声明:

<service android:name="com.example.MyJobServiceExtension"
            android:permission="android.permission.BIND_JOB_SERVICE"
            android:exported="true"
            tools:node="replace">

我从未在 onHandleWork 中看到任何回调或在我的 logcat 中看到任何错误日志。有没有人成功地集成了这个可以提供帮助?

更新 1

我在 API 级别 21 设备上测试了这个并且它工作..但它似乎没有在我的 Android Oreo Pixel XL 设备上被调用..任何线索为什么?

更新 2

此外,我似乎看到 IntentService 的 onCreate 被调用,但其他生命周期方法(包括 onHandleWork)的 none 被调用。有人遇到过这个吗?

我遇到了同样的问题(在 O 之前的设备上工作正常,没有迹象表明在 O 设备上发生任何事情)。今天,我再次尝试使用与昨​​天完全相同的代码,现在它可以工作了 - 唯一的区别是我在两者之间重新启动了设备。

我目前的理论是我的初始设置不起作用;我当前的代码确实如此,只是重新部署新代码并不能从 JobScheduler 中清除损坏的状态;重新启动或 uninstall/reinstall 包确实如此。

现在可用的设置(从以前的 IntentService 迁移而来):

<service
    android:name=".MyJobIntentService"
    android:exported="false"
    android:permission="android.permission.BIND_JOB_SERVICE"/>

并从

开始
Intent intent = new Intent(); 
intent.putExtra(EXTRA_NAME, extraValue);
JobIntentService.enqueueWork(context, MyJobIntentService.class, FIXED_JOB_ID, intent);

请注意,意图不是明确的意图(即未设置 ComponentName)。

从 IntentService 升级到 JobIntentService 后,我遇到了同样的问题。确保从旧实现中删除此方法:

@Override
public IBinder onBind(Intent intent) {
    return null;
}

对我来说,这解决了问题,现在它适用于 pre- 和 post-Oreo。

对我来说,我仍然在 enqueueWork 之后启动服务,因此给我错误。

我 运行 尝试使用 JobSchedulerJobIntentService 加入队列。虽然 JobScheduler 有自己的 enqueueWork() 方法,但它不适用于 JobIntentService。该服务将启动,但永远不会调用 onHandleWork()

当我使用 JobIntentService 上的 static enqueueWork() 方法时它再次开始工作 - 例如:

MyJobIntentService.enqueueWork(context, ...)

None 通过阅读 Android 的 javadoc 可以明显看出这一点。

这对我有用,

按照@agirardello

的建议删除IBind覆盖

并添加了以下内容

@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
    return super.onStartCommand(intent, flags, startId);
}

不知道为什么会这样。

如果您在 JobIntentService 中覆盖了 onCreate 方法,它将阻止调用 onHandleWork。

我将我的 Service 转换为 JobIntentService,只有在我删除 onCreate 方法后它才起作用。

请尝试退出并再次 运行 Android Studio。然后再测试。 就我而言,Android Studio 的版本是 v 3.3.1。 查看正常工作的示例代码。

public class CustomizedIntentService extends JobIntentService
{
    public static final String MY_ACTION = "action.SOME_ACTION";
    private static final int MY_JOB_INTENT_SERVICE_ID = 500;

    public CustomizedIntentService() {
    }

    // Helper Methods to start this JobIntentService.
    public static void enqueueJobAction(Context context, String action) {
        Intent intent = new Intent(context, CustomizedIntentService.class);
        intent.setAction(MY_ACTION);

        enqueueWork(context, CustomizedIntentService.class, MY_JOB_INTENT_SERVICE_ID, intent);
    }

    @Override
    protected void onHandleWork(@NonNull Intent intent) {
        String action = intent.getAction();

        // action will be "action.SOME_ACTION"
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public boolean onStopCurrentWork() {
        return super.onStopCurrentWork();
    }
}

// 根据需要启动 JobIntentService。

CustomizedIntentService.enqueueJobAction(上下文,CustomizedIntentService.MY_ACTION);

虽然这听起来很有趣,但我有一个类似的问题,因为我没有在 enqueueWork() 中将 class 的名称更改为它自己的名称,因为我从我的 classes。 我更新后它开始正常工作了。

我遇到了一个有点类似的问题,从 Service 迁移到 JobIntentService 后,onHandleWork 没有被第二次调用。日志显示 enqueueWork 已被调用,但 onHandleWork 仅执行第一个并且似乎被卡住了。

经过更多的挖掘和记录,我发现不同之处在于 "stuck" 场景中有 JobIntentService#onDestroy,即使 onHandleWork 中的所有操作都已执行并且看似已完成。

原来罪魁祸首是 bindService 调用该服务到 activity 生命周期,这阻止了第一个作业的处理,并且出于某种原因在这种情况导致之后调用 enqueueWork "stuck" 的服务,再也不会 运行 以下任何一项 onHandleWork

因此,这是一个不正确的事件日志,其中 JobIntentService 在第一次调用后似乎卡住了,再也不会触发 onHandleWork

enqueueWork -> first call
onHandleWork started (log in the first line)
onHandleWork finished (log in the last line)
enqueueWork -> second call
enqueueWork -> third call

下面是删除 bindService 调用后 JobIntentService 正常运行的正确事件日志:

enqueueWork -> first call
onHandleWork started (log in the first line)
onHandleWork finished (log in the last line)
onDestroy (service is destroyed after the job is finished)
enqueueWork -> second call
onHandleWork started (log in the first line)
onHandleWork finished (log in the last line)
onDestroy
enqueueWork -> third call
onHandleWork started (log in the first line)
onHandleWork finished (log in the last line)
onDestroy

希望这对某人有所帮助。

我终于找到了那个问题的解决方案大声笑

如果您重写 "onBind" 方法并使用 "enqueueWork" 方法调用工作,您需要 return 绑定到工作的引擎:

@Override @Nullable
    public IBinder onBind(@NonNull Intent intent) {
        [... Do What You Want ... ]
        return super.onBind(intent);
    }

因此 return 使用 "super.onBind" 方法的 IBinder,因此您必须使用它来绑定到 JobIntentService。

如果您想绑定 return 另一个活页夹,您可以这样做:

@Override @Nullable
    public IBinder onBind(@NonNull Intent intent) {
        IBinder binder = initSynchronizer();
        new Thread(
                () -> onHandleWork(intent)
            ).start();
        return binder;
    }

因此,让您 "onHandleWork" 在另一个线程中开始。 这样你可以使用:

"bindService(....., JobIntentService.BIND_AUTO_CREATE);"

绑定到服务和 return 您的活页夹。 无论如何,当您与服务解除绑定时,该服务将被终止,如果它仍然是 运行,则您无法再次绑定到它,因为该服务已被终止,但 "onHandleWork" 所在的线程仍然是 运行宁...

所以我建议您仅在必须执行需要与 activity 通信的任务时才使用此版本,直到它还活着并且需要在 activity 被杀死时继续工作(无法再次绑定 jobService,只能启动一个新的...)

要在解除绑定后不终止服务,您需要在 "foreground" 和 "onDestroy" 中的 "stopForeground" 中启动它。这样,您的服务仍然只针对处理 "onHandleWork" 方法的线程。

我希望 google 能快速解决这个问题 LoL,我将所有旧的 "Service" 和 "IntentService" 转换为新的工作但是...他们工作真的比以前更糟了!

再见,祝你编码愉快 ;)

对于无法通过其他答案解决问题的所有人:

每次调用 enqueueWork 时尝试使用不同的 JOB_IDs。如果之前的作业没有完成,服务可能会卡住(类似于用户 "git pull origin" 描述的问题),使用不同 ID 的新作业可能会解决这个问题。

我认为我有这样的问题,因为我试图在 onHandleWork() 中吐司一些文本,但实际上问题是它是错误的。我应该使用 Handler。如果使用 AsyncTask 子类在 onHandleWork() 内的另一个线程上执行,这可能是个问题,这是一个非常糟糕的主意。