自定义JobIntentService onHandleWork未调用

时间:2017-09-12 00:56:53

标签: android android-8.0-oreo jobservice

我最近正在更新一个应用程序,我使用JobIntentService而不是常规的IntentService处理来自push的通知,因为它似乎是在棒棒糖前设备和帖子上处理此问题的正确方法。我这样排队工作:

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中的任何错误日志。有没有人成功整合这个可以帮助?

更新:我在api level 21设备上进行了测试,但它确实有效..但它似乎没有在我的Android O像素XL设备上调用..任何线索为什么?

更新#2:我似乎也看到了intentservice的onCreate被调用,但没有其他生命周期方法(包括onHandleWork)。有没有人遇到过这个?

12 个答案:

答案 0 :(得分:53)

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

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

对我而言,这解决了这个问题,现在它在奥利奥之前和之后都有效。

答案 1 :(得分:7)

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

我目前的理论是我的初始设置不起作用;我当前的那个,只是重新部署新代码并没有清除JobScheduler中的破坏状态;重新启动或卸载/重新安装软件包。

现在正在运行的设置(从以前的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)。

答案 2 :(得分:2)

我遇到了这个问题,尝试使用JobIntentServiceJobScheduler排入队列。虽然JobScheduler有自己的enqueueWork()方法,但它不能与JobIntentService一起使用。该服务将启动,但永远不会调用onHandleWork()。

当我使用JobIntentService上的静态enqueueWork()方法时,它又开始工作了 - 例如:

MyJobIntentService.enqueueWork(context, ...)

通过阅读Android的javadoc,这一切都不明显。

答案 3 :(得分:2)

这对我有用,

按照@agirardello

的建议删除IBind覆盖

并添加以下内容

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

不知道为什么会这样。

答案 4 :(得分:2)

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

我将Service转换为JobIntentService,并且只有在删除onCreate方法后才有效。

答案 5 :(得分:1)

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

经过更多的挖掘和记录后,我发现区别在于,在“卡住”的情况下,JobIntentService#onDestroy中有onHandleWork,尽管bindService中的所有操作都已执行并且看似已完成。

事实证明,罪魁祸首是该服务进入活动生命周期的enqueueWork调用,这阻止了处理第一份工作,并且由于某种原因在这种情况导致该服务“卡住”后调用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

JobIntentService

这是正确的事件日志,其中bindService在删除了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 调用后正常运行:

z[apply.monthly(z$date,max,by = z$seriesid)]

希望这对某人有帮助。

答案 6 :(得分:0)

对于我来说,我仍然在enqueueWork之后开始服务,并因此而给我错误。

答案 7 :(得分:0)

只需尝试退出并再次运行Android Studio。然后再次测试。 就我而言,Android Studio的版本为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(context,CustomizedIntentService.MY_ACTION);

答案 8 :(得分:0)

听起来可能很有趣,但是我遇到了类似的问题,因为我没有在enqueueWork()中将类的名称更改为其自己的名称,因为我从一个类中复制了代码。 在进行更新后,它开始正常工作。

答案 9 :(得分:0)

我终于找到了解决这个问题的方法

如果您覆盖“ onBind”方法,并且您使用“ enqueueWork”方法调用工作,则需要将绑定返回执行此操作的工作引擎:

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

因此返回“ super.onBind”方法的IBinder,因此必须使用该绑定器绑定到JobIntentService。

如果您想绑定并返回另一个绑定器,您可以这样做:

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

因此,通过在另一个线程中启动“ onHandleWork”。 这样您可以使用:

“ bindService(.....,JobIntentService.BIND_AUTO_CREATE);”

绑定到服务并返回您的活页夹。 无论如何,当您与服务解除绑定时,该服务将被终止,并且如果该服务仍在运行,您将无法再次绑定到该服务,因为该服务已被终止,但是“ onHandleWork”所在的线程仍在运行...

因此,我建议您仅在必须执行需要与活动进行通信直到活动生效之前必须与活动进行通信的任务时才使用此版本,并且如果活动被杀死(并且无法再次绑定jobService,但只是开始一个新的...)

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

我希望Google能够解决这种快速的LoL,我将所有较旧的“ Service”和“ IntentService”都转换为新的工作,但是...它们的工作确实比以前更糟糕!

再见,编码不错;)

答案 10 :(得分:0)

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

每次调用 enqueueWork 时,尝试使用不同的 JOB_ID 。如果先前的作业尚未完成,则服务可能会卡住(类似于用户“ git pull origin”所描述的问题),而具有不同ID的新作业可能会解决此问题。

答案 11 :(得分:0)

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