Long running service consumes a lot of battery

后端 未结 1 606
甜味超标
甜味超标 2021-02-15 14:33

I developed an app and some people complains that it takes too much battery, it is the second most consuming process after the screen. However, in some devices it does not consu

1条回答
  •  渐次进展
    2021-02-15 14:47

    Running services all the time can be expensive regarding CPU and battery - that's one of the downsides of a service. In particular if you include threads that cause some CPU load. There are some options to choose from, depending on your app requirements:

    1. If the result of your service is only relevant at the time when the user can consume it you might think about stopping and starting your service on screen on and off events - or at least starting and stopping included threads/handlers. This can be done by using a BroadcastReceiver:

      public class ScreenReceiver extends BroadcastReceiver {
      
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
                // (1) stop service or (2) stop all threads and unregister all event 
                // handlers, if the service has to register the screen receiver
            } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
                // (1) start service or (2) start all threads and register all event
                // handlers as needed
            }
        }
      }
      

      Note that screen events have to be registered programmatically. If you have to register the screen on and off events inside of the same service, start it as sticky. This way the service instance will be kept. (examples: battery widgets, weather information, ...)

    2. In case you have an event based environment you could think about using Google Cloud Messaging (GCM). With GCM you can send a message from any of your servers to any registered device causing it to wake up and process incoming information. No need to poll for information all the time.

      Check out Googles documentation and examples, if this scenario fits to your requirements (examples: messaging app, chat app, ...)

    3. If you need to process/run data/code regularly you might think about using an AlarmManager:

      public void SetAlarm(Context context) {
        AlarmManager manager = (AlarmManager)context.
                                getSystemService(Context.ALARM_SERVICE);
      
        Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
        PendingIntent pendingIntent = 
                      PendingIntent.getBroadcast(context, 0, intent, 0);
      
        am.setRepeating(AlarmManager.RTC_WAKEUP, 
                        System.currentTimeMillis(), 1000 *60 , pendingIntent);
      }
      

      However, the downside is that it is not a good option for short intervals (lets say smaller than 30 minutes). (examples: email client, ...)

    So there are some alternatives. Looking at your code I can see you are doing something with sensors. Do you need the sensor information, if the screen is off? Or what kind of events could trigger the start and end of your service?

    If you really need the results all the time (for instance for a GPS tracker), you've probably no other choice than optimizing your code. May be it make sense to stop the service, if the battery is low (see this for more details).

    Good luck!

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