37

我最近正在更新一个我正在开发的应用程序,以使用 aJobIntentService而不是常规来处理来自推送的通知,IntentService因为它似乎是在棒棒糖之前的设备上处理此问题以及发布的正确方法。我正在排队工作:

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

此外,我似乎看到 IntentServiceonCreate被调用,但没有其他生命周期方法(包括onHandleWork)。有没有人遇到过这种情况?

4

12 回答 12

70

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

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

对我来说,这解决了问题,现在它适用于奥利奥前后。

于 2017-09-16T15:29:17.830 回答
9

我遇到了同样的问题(在预 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)。

于 2017-09-13T08:39:05.323 回答
3

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

我将我的转换ServiceJobIntentService并且只有在我删除了onCreate它有效的方法之后。

于 2018-11-07T18:02:39.407 回答
3

这对我有用,

IBind按照@agirardello 的建议删除覆盖

并添加了以下内容

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

不知道为什么会这样。

于 2018-02-28T17:04:44.010 回答
2

我在尝试将JobIntentServiceusing排队时遇到了这个问题JobScheduler。虽然JobScheduler有自己的enqueueWork()方法,但它不适用于JobIntentService. 该服务将启动但onHandleWork()永远不会被调用。

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

MyJobIntentService.enqueueWork(context, ...)

从阅读 Android 的 javadoc 来看,这一切都不是显而易见的。

于 2017-10-18T01:04:18.110 回答
1

我遇到了一个有点类似的问题,onHandleWork从迁移ServiceJobIntentService. 日志显示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

希望这对某人有所帮助。

于 2019-05-01T07:43:35.693 回答
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”。这样你就可以使用:

“绑定服务(.....,JobIntentService.BIND_AUTO_CREATE);”

绑定到服务并返回您的活页夹。无论如何,当您从服务中取消绑定时,服务将被终止,如果它仍然运行,您将无法再次绑定到它,因为服务被终止但“onHandleWork”仍在运行的线程......

因此,我建议您仅在必须执行需要与 Activity 通信直到它处于活动状态并且在 Activity 被杀死时仍需要继续工作的任务时才使用此版本(不可能再次绑定 jobService,但仅用于开始一个新的......)

要在取消绑定后不终止服务,您需要在“onDestroy”中的“前台”“stopForeground”中启动它。这样,您的服务仍然只为处理“onHandleWork”方法的线程而存在。

我希望谷歌能解决这个非常快的大声笑,我将所有旧的“服务”和“意图服务”转换为新的工作,但是......他们的工作真的比以前更糟糕!

再见有一个很好的编码;)

于 2019-05-02T07:33:49.727 回答
0

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

于 2019-09-17T09:51:01.900 回答
0

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

于 2017-09-26T20:14:02.333 回答
0

只需尝试退出并再次运行 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(context, CustomizedIntentService.MY_ACTION);

于 2019-02-14T05:56:10.360 回答
0

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

于 2019-04-05T13:07:23.567 回答
-2

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

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

于 2019-07-07T15:42:07.937 回答