Android Oreo JobIntentService Keep running in background for Android 7 &below and crashing often in Android 8 & above

前端 未结 3 723
野趣味
野趣味 2021-02-06 09:50

I have recently replaced all my service to foreground services and JobIntentService since there are some background execution limits (https://developer.android.com/about/version

相关标签:
3条回答
  • 2021-02-06 10:19

    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..

    0 讨论(0)
  • 2021-02-06 10:24

    I think you just need this much of a code. Create a new Class MyJobIntentService and write this much of a code and call postData() to start your service.

    public class MyJobIntentService extends JobIntentService {
    
    public static void postData(Context context, String data) {
        final Intent intent = new Intent(context, MyJobIntentService.class);
        intent.setAction(INITIAL_ACTION);
        intent.putExtra(SAMPLE_ID, data);
        enqueueWork(context, MyJobIntentService.class, 1000, intent);
    }
    
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    
    @Override
    public void onDestroy() {
        Ln.d("Cancelled service");
        super.onDestroy();
    }
    
    @Override
        protected void onHandleWork(@NonNull Intent intent) {
            if (intent != null) {
                final 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 ");
                }
            }
        }
    }
    

    And make sure to add your service in manifest file

    <service
                android:name="service.MyJobIntentService"
                android:exported="false"
                android:permission="android.permission.BIND_JOB_SERVICE" />
    
    0 讨论(0)
  • 2021-02-06 10:36

    JobIntentService which acts like Intent Service is not getting stopped once the work is done

    The issue is in your extended class FixedJobIntentService dequeueWork method.

    Try changing it to something like below

    GenericWorkItem superValue = super.dequeueWork();
    if (superValue != null) {
        return new FixedGenericWorkItem(superValue);
    }
    return null;
    

    Looking at the JobIntentSerivce code, Work Items processor logic is below, i.e until there are no work items left in the queue all items are processed (i.e onHandleWork is called for each item)

        while ((work = dequeueWork()) != null) {
            if (DEBUG) Log.d(TAG, "Processing next work: " + work);
            onHandleWork(work.getIntent());
            if (DEBUG) Log.d(TAG, "Completing work: " + work);
            work.complete();
        }
    

    Issue in your implementation is after processing the first work item, the super.dequeueWork() returns null, which you are not taking care of and just sending a new FixedGenericWorkItem object passing null value. You might observe that a null value is passed to your onHandleWork in your subsequent calls.

    Hope this helps resolve your issue.

    0 讨论(0)
提交回复
热议问题