IntentService, PendingIntent, and AlarmManager: Cannot keep process running indefinitely?

我的未来我决定 提交于 2019-12-08 12:08:22

问题


I've got a pretty simple app that runs two services in the background, using IntentService with AlarmManager. One is a "messaging" service that sends a JSON request and parses the response, the other polls for location from a LocationManager. The requirement here is that they run on an interval, indefinitely, until manually stopped by the user, with a button - even if the device's screen hasn't been turned on for days. The services must never stop. Battery life is not a concern.

My minimum-supported API is 4.1 and I'm testing on 4.1, 4.2, and 4.4 devices. On my Nexus 7 and GPad, 4.4.4 and 4.4.2, respectively, the services will run indefinitely and work as expected. On a Galaxy Tab 3 running 4.2, the device seemed to go to sleep after 8 hrs. or so of inactivity, and would then quit reporting location and polling. The 4.1 devices seem to do the same.

With that hunch, I added this to the messaging service to manually wake the CPU. This one runs every 60 sec. so I had hoped it would prevent the devices from ever going to sleep.

@Override
protected void onHandleIntent(Intent intent)
{                       
    PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wl = pm.newWakeLock(
            PowerManager.PARTIAL_WAKE_LOCK, 
            "com.service.MESSAGE_SERVICE_WAKE_LOCK");

    wl.acquire();

    //poll for messages via JSON    

    wl.release();               
}

Setting the AlarmManager like so (pi = PendingIntent...passing in the IntentService class):

alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), pollInterval, pi);

This appeared to fix things for my own testing, and the devices are consistently reporting location for me on 4.4 and 4.2. However, the 4.1 testers have reported that it still goes to sleep on them after about 8 hrs. I also tested it on a friend's Galaxy S5 (4.4.2) and it quit reporting location after a few hours.

This is my first app and this part has been especially frustrating. Am I doing something wrong? Any idea why these services might stop running? Happy to provide more code if that helps...thought I'd start with this, at least.


回答1:


Alarms which use PendingIntent for a Service are not guaranteed to keep the device awake long enough for the Service to be started or resumed. In the case of an IntentService, the service automatically dies once it has processed all queued Intent objects. You'll need to use a PendingIntent for a BroadcastReceiver which takes a WakeLock and starts your Service. Your Service can then release the wakelock when it is done with its work, allowing the device to go back to sleep.




回答2:


If you wish for a service to "always" run, you shouldn't make is a background service.

Make it a foreground service instead:

A foreground service is a service that's considered to be something the user is actively aware of and thus not a candidate for the system to kill when low on memory.

In order to try out how long your service can run when the OS has low RAM, you can try this sample I've made (which I've posted here, and uses this library I've made), which uses more and more RAM (real RAM, not of the heap). It causes the OS to kill other processes and eventually kill the process of the sample itself.

If you just want your services to run every X hours/minutes, you don't need this at all, and what you've found seems ok.



来源:https://stackoverflow.com/questions/27365381/intentservice-pendingintent-and-alarmmanager-cannot-keep-process-running-inde

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!