未调用自定义 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 之后启动服务,因此给我错误。
我 运行 尝试使用 JobScheduler
将 JobIntentService
加入队列。虽然 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()
内的另一个线程上执行,这可能是个问题,这是一个非常糟糕的主意。
我最近正在更新我正在使用 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 之后启动服务,因此给我错误。
我 运行 尝试使用 JobScheduler
将 JobIntentService
加入队列。虽然 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()
内的另一个线程上执行,这可能是个问题,这是一个非常糟糕的主意。