Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Service is killed in sleep mode.Why?

I've read just about every Stackoverflow answer that exists on this topic, but none of them worked.

Goal: Keep my service running 24/7, all the time

Problem: Whenever my device is on sleep mode for an hour or more, the service is killed


What I've tried to fix it:

  • Returning START_STICKY from onStartCommand() and using startForeground()

        public int onStartCommand(Intent intent, int flags, int startId) {
    
            notification = makeStickyNotification(); //I've simplified the irrelevant code, obviously this would be a real notification I build
    
            startForeground(1234, notification);
            return START_STICKY;
            }
    

This works fine, and it even restarts my service whenever the device is low on memory, but it is not enough to fix the problem that occurs when my device goes to sleep for a while.

  • Using Alarm Manager in onCreate() of my Activity and in onStartCommand() of my Service to call a Broadcast Receiver that calls my service

            Intent ll24 = new Intent(this, AlarmReceiver.class);
    
            PendingIntent recurringLl24 = PendingIntent.getBroadcast(this, 0, ll24, PendingIntent.FLAG_CANCEL_CURRENT);
    
            AlarmManager alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    
            alarms.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000*60, recurringLl24); // Every minute
    

This helps keep my service active, but again, doesn't solve my problem

  • Using Schedule Task Executor to keep it alive

     if (scheduleTaskExecutor == null) {
    
            scheduleTaskExecutor = Executors.newScheduledThreadPool(1);
    
            scheduleTaskExecutor.scheduleAtFixedRate(new mainTask(), 0, 1, TimeUnit.SECONDS);
    
        }
    ...    
    class mainTask implements Runnable {
    
    public void run() {
        // 1 Second Timer
       }
    }
    

    This also just keeps the service active but doesn't keep it alive after a long sleep.

  • Separate task Manifest

    android:launchMode="singleTop"

This did nothing

How can I (1) test this issue without having to put my phone to sleep and check every hour and (2) keep my service running despite the device going to sleep?

like image 713
Ruchir Baronia Avatar asked Jul 21 '18 21:07

Ruchir Baronia


Video Answer


1 Answers

The murder mystery has been solved, and I know what killed my service. Here's what I did:

  1. After I realized that startsticky, startforeground, alarmmanager, scheduleTaskExecutor, and even wakelock were unable to save my service, I realized the murderer couldn't be the Android system, because I had taken every measure possible to prevent the system from killing my service and it still would get killed.
  2. I realized I needed to look for another suspect, since the service wasn't dying because of the system. For that, I had to run an investigation. I ran the following command:

    adb shell dumpsys activity processes > tmp.txt

This would give me a detailed log of all the processes running and their system priorities. Essentially, tmp.txt would be the detective in this murder mystery.

  1. I looked through the file with lots of detail. It looked like my service was prioritized properly by the system:

    Proc #31: adj=prcp /FS trm= 0 2205:servicename.service/uID (fg-service)

The above line indicates the exact priority of a process running on the Android device. adj=prcp means the service is a visible foreground service.

At this point, I realized that my service must be encountering some error a couple hours after running, so I let it run and die. After it died, I produced a dumpsys again to examine the error:

  1. At this point, my service wasn't listed as a task in the tmp.txt file. Excited, I scrolled to the bottom of the dumpsys and solved the mystery!

com.curlybrace.ruchir.appName.MyService$2.onForeground(MyService.java:199) at com.rvalerio.fgchecker.AppChecker$2.run(AppChecker.java:118) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6123) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)

The stack trace that caused the killing of my service was displayed right there! Essentially, a variable that would check for the foreground app being used would become null after a few hours of inactivity, which would cause an exception, and kill the service!

Key Takeaways: If your service is getting killed, and you've done everything you can to make sure that it shouldn't be killed, perform a dumpsys and examine the nitty gritty of your device's activity process. I guarantee you will find the issue that way.

I still would like to have the bounty awarded to @Khemraj since his answer could be a great solution for someone who hasn't started their service properly. However, I am accepting this answer since it is the solution that actually fixed the issue.

like image 79
Ruchir Baronia Avatar answered Sep 23 '22 01:09

Ruchir Baronia