【问题标题】:Custom JobIntentService onHandleWork not called未调用自定义 JobIntentService onHandleWork
【发布时间】:2017-09-12 00:56:52
【问题描述】:

我最近正在更新一个我正在开发的应用程序,以使用 JobIntentService 而不是常规的 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

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

【问题讨论】:

  • 我有同样的症状,但还没有答案。在 API 级别 23 设备上工作正常,而不是在 API 级别 26 Nexus 5X 上。你的work Intent 是如何构建的?
  • @Jule 目前我的工作意图是通过自定义操作加上一些额外内容构建的,就是这样。
  • 我有同样的问题,我实际上收到了这条消息“JobServiceContext:尝试绑定时超时...”

标签: android android-8.0-oreo jobservice jobintentservice


【解决方案1】:

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

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

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

【讨论】:

  • 哇,非常感谢!这解决了它。我希望 android 在这种情况下会给我一些错误 =_= 我实际上从未注意到尝试绑定日志时 ServiceContext 超时。
  • 可以正常工作,但我现在看到,当应用程序打开或最近时服务运行良好,但从最近删除时服务停止,请在这里帮助我
  • 还必须删除 onCreate 和 onStart 覆盖
【解决方案2】:

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

【讨论】:

  • JobIntentService.enqueueWork 替换 startForegroundService 让它在 API 26 上为我工作。
  • 确保android:exported="true"。我刚刚测试了
  • @KenZira 为什么 export 必须等于 true?
  • @KenZira 你能链接我吗?
  • 好的,但我现在看到,当应用程序打开或最近时服务运行良好,但从最近删除时服务停止,请在这里帮助我
【解决方案3】:

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

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

【讨论】:

  • 你能给出任何理由吗?
  • 在我删除了 oncreate 并添加了exported=true 之后,它确实可以在android 4.4 (19) 上运行
  • 遇到了同样的问题。这个答案帮助我找到了解决方案。我高度假设您没有在 onCreate() 方法中调用 super.onCreate() 。如果您从 Service 切换到 JobIntentService,您必须确保执行对超类的 onCreate 方法的调用。
【解决方案4】:

这对我有用,

按照@agirardello 的建议删除IBind Override

并添加以下内容

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

不知道为什么会这样。

【讨论】:

    【解决方案5】:

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

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

    MyJobIntentService.enqueueWork(context, ...)
    

    这在阅读 Android 的 javadoc 时并不明显。

    【讨论】:

      【解决方案6】:

      在从Service 迁移到JobIntentService 后,第二次调用onHandleWork 时遇到了类似的问题。日志显示 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
      

      这是删除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
      

      希望这对某人有所帮助。

      【讨论】:

      • 这就是我的情况,但从您的帖子中不清楚,您为解决问题做了什么。你能澄清一下吗?
      • 检查您的代码中是否有 bindService 调用并尝试将其删除以查看这是否解决了问题@SamikR
      • 这也发生在我身上,但我从不在代码中调用bindService
      【解决方案7】:

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

      【讨论】:

        【解决方案8】:

        只需尝试退出并再次运行 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);

        【讨论】:

          【解决方案9】:

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

          【讨论】:

            【解决方案10】:

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

            如果您覆盖“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);"

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

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

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

            我希望 google 能解决这个非常快的 LoL,我将所有旧的“服务”和“IntentService”转换为新的工作,但是......它们的工作效率比以前更差!

            再见,编码不错;)

            【讨论】:

            • 我也在使用 JobIntentService 并希望使用 onBind 将引用传递给该服务。似乎这并不是真正为此而构建的,但 onBind 允许执行该方法并传递引用。但是现在根本没有调用 onHandleWork。这个类可以使用更多的细化来限制用例。
            • @SergioCouture 你好(o ciao se sei italiano)!我认为 JobIntentService 类存在错误,因为正如您所见,它调用了“OnBind”,但之后它再也没有调用“onHandleWork”。有两种方法可以解决这个问题:您可以使用另一个类,如“服务”,其中绑定工作正常,或者您使用我上面编写的方法,手动启动“onHandleWork”。我知道这很糟糕,但我没有找到任何其他解决方案。我个人使用“服务”类在搜索 BLE 标签的后台服务中正确处理绑定。希望这对你有帮助!祝你有愉快的一天和编码:D
            【解决方案11】:

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

            【讨论】:

              【解决方案12】:

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

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

              【讨论】:

              • 这会导致java.lang.IllegalArgumentException: Given job ID 1001 is different than previous 1000
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2020-05-15
              • 2020-11-16
              • 1970-01-01
              • 2019-09-12
              • 2020-05-29
              • 1970-01-01
              • 2021-03-10
              相关资源
              最近更新 更多