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

查看:135
本文介绍了Android Oreo JobIntentService会在Android 7及以下版本的后台继续运行,并在Android 8及以下版本中经常崩溃.以上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于存在一些后台执行限制( 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 documentationno 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-exceptionavoid crash对其进行处理.再次...如果you are implementing threads within services然后try-catch-exception will not save your application from being crashing ...

**那么地狱&然后如何实施:**

使用FireBaseJobScedular:-

  1. 易于使用
  2. 使用简单的JobService
  3. 可以运行更长或更短的时间... EVEN ALL THE TIME RUNNING TASK
  4. EVEN SUPPORTED BY NON STANDARD COMPANIES像vivo,mi,oppo,one + 3,...,需要stock-android对其进行更改,并命名为FunTouchOs,ColorOs,OxygenOs
  5. 只需要将电池设置更改为请勿优化此应用"
  6. 是的,google正式支持它,建议使用它
  7. 它创建GooglePlyService的实例并在其中运行,而且显然非标准公司也不会限制google应用执行其任务.
  8. Oreo上工作..,即使我已经在Android P上对其进行了测试,并且在Android 5.0以下版本中都可以作为AlarmManager任务来工作.
  9. 还是建议您使用minsdk above 16target sdk 26,好像您要将应用程序上载到google play一样,这是强制性的,并且会听到您的消息.和compile sdk 26.
  10. 只需将您的JobService绑定到清单中,并使用receive_boot_complete
  11. 的单行权限
  12. 只需对其进行计划...它将在每个制造商的市场上的每个设备上启动...甚至在cold boothot boot
  13. 上也可以启动
  14. 它最大限度地减少了很多代码和you can focus on actual tasks.
  15. 任务完成后,您可以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 :-

  1. Easy to use
  2. Uses simple JobService
  3. Can run longer or smaller time tasks... EVEN ALL THE TIME RUNNING TASK
  4. EVEN SUPPORTED BY NON STANDARD COMPANIES like vivo, mi, oppo, one+3, ... which takes stock-android makes changes to it and gives names like FunTouchOs, ColorOs, OxygenOs
  5. Just need to Do change battery settings to "Do not optimise this app"
  6. Yes google supports it officially and recommends to use it
  7. 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.
  8. Works on Oreo .., Even i have tested it on Android P and works below Android version 5.0 as AlarmManager tasks.
  9. Still i recommends to use minsdk above 16, target sdk 26 as if in case you wants to upload your app to google play it is compulsory now and that news would have been heard you. and compile sdk 26.
  10. Just Bind Your JobService in manifest and use a single line permission of receive_boot_complete
  11. Just schedule it ... And it will be started on every device in market from every manufacturer... even on cold boot and hot boot
  12. It minimises a lot, lot and lot of code and you can focus on actual tasks.
  13. 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 and project is related to... and what you exactly wants to be done in a foreground 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆