我做了很多试验和错误编程,并找到了解决方案。所以,我回答我自己的问题。
服务重启时的 Android 行为:
众所周知,Android 服务可以在资源紧张的情况下被系统强制停止。Android 会自动重启该服务。这是不可避免的,您需要对服务进行编程以优雅地处理这种情况。请注意,服务强制停止和重新启动之间存在延迟。这种延迟似乎是随机的,可能以数小时为单位。我发现这种延迟是有规律的。在第一次强制停止后,Android 会在 5000 毫秒(5 秒)内重新启动应用程序。此外,如果在第一次重启后 60 秒内再次强制停止服务(第二次),Android 会将下次重启的延迟更新 4 次(即 5000 x 4 = 20000ms = 20 秒)。20 秒后,Android 再次重启服务(第三次)。如果在 60 秒内再次强制停止服务(第三次),第三次重启后延迟更新为 4 次 20000 ms = 80000 ms = 80 秒,以此类推。因此,如果您的服务在自动重启后的 60 秒内被强制终止,则延迟会呈指数级增长(5 秒、20 秒、80 秒、320 秒、1280 秒……)。如果您的服务在 60 秒内没有再次被强制终止,则延迟计时器将重置为 5 秒以进行下一次强制停止并重新启动。在我看来,超过 20 秒的重启计时器是不合理的,如果您甚至不确定您的服务是否正在运行,程序员应该如何使用服务编写可靠的应用程序?如果您的服务在自动重启后的 60 秒内被强制终止,则延迟呈指数级增长(5 秒、20 秒、80 秒、320 秒、1280 秒……)。如果您的服务在 60 秒内没有再次被强制终止,则延迟计时器将重置为 5 秒以进行下一次强制停止并重新启动。在我看来,超过 20 秒的重启计时器是不合理的,如果您甚至不确定您的服务是否正在运行,程序员应该如何使用服务编写可靠的应用程序?如果您的服务在自动重启后的 60 秒内被强制终止,则延迟呈指数级增长(5 秒、20 秒、80 秒、320 秒、1280 秒……)。如果您的服务在 60 秒内没有再次被强制终止,则延迟计时器将重置为 5 秒以进行下一次强制停止并重新启动。在我看来,超过 20 秒的重启计时器是不合理的,如果您甚至不确定您的服务是否正在运行,程序员应该如何使用服务编写可靠的应用程序?
已知的解决方案和变通方法:
堆栈溢出中已经有几个答案,重点是如何确保您的服务一开始就不会被杀死。其中最重要的是让服务在前台启动。请参阅此处以了解如何执行此操作。这会在服务启动时引起通知。在前台启动服务可确保它几乎不会被杀死。还有其他建议的方法,例如从您的服务中生成一个连续运行的线程(该线程不必做任何事情)。这应该提高线程的“重要性”,并且服务不会经常被杀死。但是,我怀疑这可能会耗尽电池。
我发现的新解决方案:
我发现了另一种绕过此问题的方法,它不需要前台服务或电池耗尽线程。当意图为空时,您只需在 onStartCommand 的服务中调用 startService() (即,这是服务的系统重新启动,假设服务创建之前返回了 START_STICKY)。当您调用 startService() 时,重新启动计时器延迟始终重置为 5 秒。下面的示例
public class MyService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
if( null == intent )
{
Log.d( "MyServiceTag", "This is a System Restart");
/* restart the service with startService().
* This will ensure that the delay between system force-stop and restart
* is always 5 seconds
*/
startService( new Intent( getBaseContext(), MyService.class));
}
return START_STICKY;
}
@Override
public void onDestroy()
{
Log.d( "MyServiceTag", "In onDestroy");
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
如果您有一个更复杂的场景,您通过意图将参数传递给您的服务并且您正在使用 START_REDELIVER_INTENT,您可能需要使用“标志”来发现重新启动并在调用 startService 之前在您的意图中重新创建附加参数()。
为我工作。希望这可以帮助。