Android Oreo JobIntentService会在Android 7及以下版本的后台继续运行,并在Android 8及以下版本中经常崩溃.以上 [英] Android Oreo JobIntentService Keep running in background for Android 7 &below and crashing often in Android 8 & above
问题描述
由于存在一些后台执行限制( https://issuetracker.google.com/issues/63622293 ,我添加了一些极客建议的临时修复程序.
Android 7&下方: 工作完成后,像Intent Service一样的JobIntentService不会停止.
我已在服务中实现JobIntentService,只要用户执行某些操作,该服务就会触发.
代码
public class SampleJobIntentService extends FixedJobIntentService {
public static void postData(Context context, String data) {
Intent intent = new Intent(context, SampleJobIntentService.class);
intent.setAction(INITIAL_ACTION);
intent.putExtra(SAMPLE_ID, data);
SampleJobIntentService.enqueueWork(context,intent);
}
public static void enqueueWork(Context context, Intent work) {
SampleJobIntentService.enqueueWork(context, SampleJobIntentService.class, JOB_ID, work);
@Override
protected void onHandleWork(@NonNull Intent intent) {
if (intent != null) {
SampleRequest sampleRequest = requests.get(intent.getAction());
if (sampleRequest != null) {
try {
// perform some networking operations
} catch (Exception ex) {
Log.d("Error for intent ");
}
Log.i("send action ");
} else
Log.e("action not found for ");
}
}
}
为避免JobIntentService崩溃,我从 https://issuetracker.google.com/Issues/63622293
public abstract class FixedJobIntentService extends JobIntentService {
@Override
GenericWorkItem dequeueWork() {
try {
return new FixedGenericWorkItem(super.dequeueWork());
} catch (SecurityException ignored) {
doStopCurrentWork();
}
return null;
}
private class FixedGenericWorkItem implements GenericWorkItem {
final GenericWorkItem mGenericWorkItem;
FixedGenericWorkItem(GenericWorkItem genericWorkItem) {
mGenericWorkItem = genericWorkItem;
}
@Override
public Intent getIntent() {
if (mGenericWorkItem != null) {
return mGenericWorkItem.getIntent();
}
return null;
}
@Override
public void complete() {
try {
if (mGenericWorkItem != null) {
mGenericWorkItem.complete();
}
} catch (IllegalArgumentException ignored) {
doStopCurrentWork();
}
}
}
}
嗯...,这是一个很大的理论...!它不可能将所有内容都放在这里.我会尽力而为,这将使您的一些概念变得清晰.
我已经失去了整整2年的阅读google文档的机会... ... use-less
...使用no proper documentation
和no proper sample codes for its developers
.. !!所以我在stack-overflow
的每篇文章中都提到了这一点,因为这将有助于节省其他人的时间.
看起来你是一个优秀的程序员;只需要一些hints to your posted question
:
提示1:
您:-我最近将我的所有服务替换为前台服务,并且 JobIntentService
前台服务:
如果需要ALL THE TIME RUNNING PROCESS; WHICH WILL NEVER END... ONCE IT IS STARTED
,则将其用于服务中,该服务将从其OnStartCommand
返回START_STICKY
.不建议再次使用它,就像您想不惜一切代价实施它一样...那么您将不得不使用带有setOngoing(true)
的通知,该最终用户将无法清除您的通知,它将永远存在....
使用前台服务:
接收者也受到限制;从Oreo
开始,您不能通过在清单中声明它并仅通过使其成为接收器来使用所有接收器和意图动作.我建议只使用BootComplete
许可并使用单个receiver
来接收boot_completed
意向,如果在O之下,则调用service
,然后在O之上,调用前景服务.现在,从该前景服务中,为所有人实现运行时接收器,并在Ondestroy方法中取消注册.我从未找到用于实现运行时接收器的官方示例代码,但经过数月的艰苦努力,我终于成功实现了它.是的,由于google,这不是一个聪明的工作
何时使用前台服务:
仅当您想要实现广播接收器时....如果您不想实现任何广播接收器;远离....
提示2:
您:-我最近将我的所有服务替换为前台服务,并且
JobIntentService
**服务的质量为:**
只需做一个很小的工作...然后退出...它必须由S topSelf()
退出...同样,如果多次调用Services can cause data-loss
,则可以运行同一服务线程不止一次...如果您想让某项服务做很多工作...请使用START_STICKY
...但是再次不建议这样做,我已经建议过,何时在提示1中使用它.>
** Intentservice的质量为:**
执行相对较长的任务,并且具有property of execution serially only
如果您一次又一次调用相同的intentService
,则所有调用将保留在queue
中,并在完成one by one
后将在one by one
中执行. .如上所述,服务中的情况并非如此.它本身就结束了...不需要由开发人员来结束.. !!
**所有产品的独特品质:**
一旦他们成为crashed
,则android可以在以后使他们停止通话,而不会在崩溃时通知您.需要使用try-catch-exception
至avoid crash
对其进行处理.再次...如果you are implementing threads within services
然后try-catch-exception
will not save your application from being crashing
...
**那么地狱&然后如何实施:**
使用FireBaseJobScedular
:-
- 易于使用
- 使用简单的JobService
- 可以运行更长或更短的时间...
EVEN ALL THE TIME RUNNING TASK
-
EVEN SUPPORTED BY NON STANDARD COMPANIES
像vivo,mi,oppo,one + 3,...,需要stock-android
对其进行更改,并命名为FunTouchOs,ColorOs,OxygenOs - 只需要将电池设置更改为请勿优化此应用"
- 是的,google正式支持它,建议使用它
- 它创建
GooglePlyService
的实例并在其中运行,而且显然非标准公司也不会限制google应用执行其任务. - 在
Oreo
上工作..,即使我已经在Android P
上对其进行了测试,并且在Android 5.0以下版本中都可以作为AlarmManager
任务来工作. - 还是建议您使用
minsdk above 16
,target sdk 26
,好像您要将应用程序上载到google play
一样,这是强制性的,并且会听到您的消息.和compile sdk 26
. - 只需将您的
JobService
绑定到清单中,并使用receive_boot_complete
的单行权限
- 只需对其进行计划...它将在每个制造商的市场上的每个设备上启动...甚至在
cold boot
和hot boot
上也可以启动
- 它最大限度地减少了很多代码和
you can focus on actual tasks
. - 任务完成后,您可以
return false
表示任务已完成,它将结束JobService.
为什么我要提出建议,因为我是一家很好的UNKNOwn
公司的CTO
,并且在许多类型的android手机制造商中都经历过foreground service
所引起的问题...不是Apple and ios
所以我们不得不经历.自从过去18年以来一直保持开发人员状态,我现在也主要编写代码...在所有开发项目中,其开发策略仅由我自己考虑.
更正我...也...您没有提到
what your tasks
并且project
与...有关,而您确实想要在foreground service and intent-service
...让我知道...,很高兴能为您提供帮助.这是一个一般性的理论答案,而不是您想要的....但是要给您实际的答案,我需要确切的项目范围.
I have recently replaced all my service to foreground services and JobIntentService since there are some background execution limits (https://developer.android.com/about/versions/oreo/background) in oreo and above. As per documentation, JobIntentService acts like Intent Service for Android 7 & below and acts like JobScheduler for Android 8 & above. I have noticed there is an issue in new JobIntentService provided by Google.
Android 8 & above:
There is a crash happening continuously in android 8 and above. There was a ticket raised here mentioning about the same issue https://issuetracker.google.com/issues/63622293 and I have added a temp fix suggested by few geeks.
Android 7 & below: JobIntentService which acts like Intent Service is not getting stopped once the work is done.
I have implemented JobIntentService within a service which triggers whenever some action is performed by a user.
Code
public class SampleJobIntentService extends FixedJobIntentService {
public static void postData(Context context, String data) {
Intent intent = new Intent(context, SampleJobIntentService.class);
intent.setAction(INITIAL_ACTION);
intent.putExtra(SAMPLE_ID, data);
SampleJobIntentService.enqueueWork(context,intent);
}
public static void enqueueWork(Context context, Intent work) {
SampleJobIntentService.enqueueWork(context, SampleJobIntentService.class, JOB_ID, work);
@Override
protected void onHandleWork(@NonNull Intent intent) {
if (intent != null) {
SampleRequest sampleRequest = requests.get(intent.getAction());
if (sampleRequest != null) {
try {
// perform some networking operations
} catch (Exception ex) {
Log.d("Error for intent ");
}
Log.i("send action ");
} else
Log.e("action not found for ");
}
}
}
To avoid the crash with JobIntentService, I took few references from https://issuetracker.google.com/issues/63622293
public abstract class FixedJobIntentService extends JobIntentService {
@Override
GenericWorkItem dequeueWork() {
try {
return new FixedGenericWorkItem(super.dequeueWork());
} catch (SecurityException ignored) {
doStopCurrentWork();
}
return null;
}
private class FixedGenericWorkItem implements GenericWorkItem {
final GenericWorkItem mGenericWorkItem;
FixedGenericWorkItem(GenericWorkItem genericWorkItem) {
mGenericWorkItem = genericWorkItem;
}
@Override
public Intent getIntent() {
if (mGenericWorkItem != null) {
return mGenericWorkItem.getIntent();
}
return null;
}
@Override
public void complete() {
try {
if (mGenericWorkItem != null) {
mGenericWorkItem.complete();
}
} catch (IllegalArgumentException ignored) {
doStopCurrentWork();
}
}
}
}
Well..., Its a lot big theory...!! It would not be able to put it all here. I will try my best which will make some your concepts clear.
I have already lost my 2 complete years in reading google documentations... Which are use-less
... With no proper documentation
and with no proper sample codes for its developers
..!! So i mention this in every of my posts on stack-overflow
, As it will help to save time of others..!!
It looks you are a good programmer; just need some hints to your posted question
:
Hint-1 :
YOU :- I have recently replaced all my service to foreground services and JobIntentService
foreground service :
If you need ALL THE TIME RUNNING PROCESS; WHICH WILL NEVER END... ONCE IT IS STARTED
it is used in service which returns START_STICKY
from its OnStartCommand
. Which is again not advised to use as if you want to implement it at any cost ... then you will have to use a notification with setOngoing(true)
Which end user would not be able to swipe away your notification, it will remain there forever....
Use of the foreground service :
There has been restrictions on receivers too; above Oreo
onwards and you can not use all the receivers and intent actions by declaring it in manifest and by just making a receiver... I advice to just use BootComplete
permission and use a single receiver
which receives the boot_completed
intent and calls a service
if below O and calls a foreground service above O. Now from that foreground service you implement the runtime receivers for all and unregister it in Ondestroy methods. I have never found an official sample code for implementing runtime receiver and finally i have implemented it successfully by many months hard-work... Yes it was not a smart work due to google
When to use foreground service :
Only if you want to implement broadcast receivers.... If you do not want to implement any broadcast receivers; STAY AWAY.......
Hint-2 :
YOU :- I have recently replaced all my service to foreground services and
JobIntentService
** service has its quality of :**
Just doing a very tiny work... and just exit... it has to be exited by StopSelf()
... Again, Services can cause data-loss
if called multiple times... As same service thread can be run more than once... Again if you want a service to do a lot of work... Use START_STICKY
... But again it is not recommended and i have suggested already, when to use it in Hint 1.
** Intentservice has its quality of :**
Doing a relatively long running tasks and it has property of execution serially only
If you again and again calls the same intentService
, then all calls will be kept in a queue
and will be executed one by one
after finishing one by one
. Which is not the case in service as depicted above. It ends on its own... no need to end it by a developer..!!
** Unique Quality of all :**
Once they are crashed
android can stop them calling in future without notifying you as it crashes the app. Need to be handled them with try-catch-exception
to avoid crash
. Again... If you are implementing threads within services
then try-catch-exception
will not save your application from being crashing
...
** THEN WHAT THE HELL & HOW TO IMPLEMENT IT THEN :**
Use FireBaseJobScedular
:-
- Easy to use
- Uses simple JobService
- Can run longer or smaller time tasks...
EVEN ALL THE TIME RUNNING TASK
EVEN SUPPORTED BY NON STANDARD COMPANIES
like vivo, mi, oppo, one+3, ... which takesstock-android
makes changes to it and gives names like FunTouchOs, ColorOs, OxygenOs- Just need to Do change battery settings to "Do not optimise this app"
- Yes google supports it officially and recommends to use it
- It Creates the instance of
GooglePlyService
and runs within it, And obviously non-standards companies too would not restrict google apps from being doing its tasks. - Works on
Oreo
.., Even i have tested it onAndroid P
and works below Android version 5.0 asAlarmManager
tasks. - Still i recommends to use
minsdk above 16
,target sdk 26
as if in case you wants to upload your app togoogle play
it is compulsory now and that news would have been heard you. andcompile sdk 26
. - Just Bind Your
JobService
in manifest and use a single line permission ofreceive_boot_complete
- Just schedule it ... And it will be started on every device in market from every manufacturer... even on
cold boot
andhot boot
- It minimises a lot, lot and lot of code and
you can focus on actual tasks
. - Once task is finished you can
return false
to indicate task has been finished and it will end the JobService.
Why i am suggesting because i am CTO
of a well-UNKNOwn
company and has been experienced the problems caused by foreground service
across the many types of android phone manufacturers... It is not the Apple and ios
so we had to experienced it. Remain developer since past 18 years and i mostly codes today too... in all of the development projects and its development strategies are thought by me only.
Correct me ... too... As you have not mentioned
what your tasks
andproject
is related to... and what you exactly wants to be done in aforeground service and intent-service
... Let me know..., It would be my pleasure to help you. It is a general theoretical answer rather than what you wants.... But for giving you actual answer i will need exact your project scope..
这篇关于Android Oreo JobIntentService会在Android 7及以下版本的后台继续运行,并在Android 8及以下版本中经常崩溃.以上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!