Using an AlarmManager to check periodically that m

2019-07-02 10:03发布

问题:

I have a Service which should keep a permanent connection to a server in order to receive notifications. It's critical for my app to get the messages from the server on time.

I cannot use GCM Push because the connection will be in the local network and the phone may not have any internet connection. I also know about the battery issues of keeping a permanent connection within a service, but I will let the user choose this option and inform him/her about the potential battery drain (Actually the feature makes mainly sense when the device is always in the same place connected to power). I also know that the Android system can kill my Service anytime, or even the user can use a task killer to get rid of all the services running at the time.

Said that, I thought about using an AlarmManager periodically to check whether my Service is running and restarting it in case it is not. I'm not convinced with this option, since the server can send a message after the service was killed but not yet restarted by the AlarmManager.

My question is basically whether there are better strategies to ensure that I get the messages on time?

So far all the related info I could find stand for avoiding the permanent service and use something else, but I have no other option because of the nature of my use case.

回答1:

Set your service as a foreground service (see this). Android will only kill this service in extreme situations. You can still use the alarm manager as a "safety net" to restart the service if it accidentally crashes. This is the best you can do. Nothing is 100%.



回答2:

You could look at setting up a broadcastreceiver on any number of device broadcasts like wifi connection state and boot;

<receiver android:name=".receivers.BootReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

    <receiver android:name=".receivers.WifiReceiver">
        <intent-filter>
            <action android:name="android.net.wifi.STATE_CHANGE" />
        </intent-filter>
    </receiver>