简体   繁体   中英

Using Intent Service in combination with Alarm Manager

I have used the Alarm Manager to allow the user to schedule a certain task to repeat at a certain amount of time. In the context of the application, I have an Android game where people are able to schedule when to send their ships. The Alarm Manager is working fine, alarms get kicked off at the right time etc.

What happens when an alarm is fired off (usually every hour and a bit), is that my IntentService will start communicating with the server to send the ships. This action may take 1 minute, but it can last up to 10 minutes. Even this all works fine. Alarms get fired, ships get sent, everyone happy. The problem arises at night, I go to sleep and expect when waking up that my ships have been sent all night long. Nope. Logging & notifications show that the Alarms are fired correctly, but it appears that the IntentService is killed when it's communicating with the server.

Possible cause for this is that I'm not looking at the game every once in a while like I do when I'm awake, and thus keep some form of process running which prevents the IntentService from being garbage collected.

I've already tried a LOT of things to fix this. I used to work with a BroadCastReceiver, I used to spawn ASyncTasks in the IntentService , but I've since refactored my code to not use those things anymore as they're bad practice for Services.

I have also checked this resource: http://techtej.blogspot.com.es/2011/03/android-thread-constructspart-4.html but I'm still not sure if what I'm doing is the correct thing to handle this situation. I have placed some extensive logging for the next night to review in the morning but I'd like you guys' opinion over this.

Oh I'm also requesting a WakeLock for the complete duration of the onHandleIntent function using:

PowerManager pm = (PowerManager) c.getSystemService(Context.POWER_SERVICE);                                         
this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "MyApplicationWakeLock");

My IntentService:

public class ScheduledRequestService extends IntentService {

    public ScheduledRequestService() {
        super("ScheduledRequestService");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startID){
        Logger.d("OnStartCommand!");
        return super.onStartCommand(intent, flags, startID);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        ScheduledRequest request = (ScheduledRequest) intent.getExtras().getSerializable("request");
        // This function will start a lot of client <-> server communication
        request.onExecute(this, intent);
    }

    @Override
    public void onDestroy(){
        Logger.d("OnDestroy!");
        super.onDestroy();
    }
}

So again, my question is; am I structuring this correctly? Should I use a normal Service instead of an IntentService ? Can my IntentService get garbage collected while it is handling an Intent (I think I read that this is possible)?

Can my IntentService get garbage collected while it is handling an Intent (I think I read that this is possible)?

No, but your process can be terminated.

am I structuring this correctly?

Not if you are trying to use a _WAKEUP alarm. You need to set things up more carefully in that case, and I would recommend either WakefulBroadcastReceiver or my WakefulIntentService to handle that pattern.

Should I use a normal Service instead of an IntentService ?

No, an IntentService will be fine. You may need to consider making it a foreground service using startForeground() .

Turns out the error was somewhere else than the garbage collector of Android. I was using cache which eventually led to me 'running out of ships' because on send time, it deducted the sent amount of ships from the pool. When they returned however, they were never added back to the cache. During the day I probably manually refreshed the cache or forced Android to clear it by using my phone otherwise which didn't cause the problem to arise (as much).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM