android - 如果不保证调用onDestory()服务,我应该在哪里发布/删除监听器等?

时间:2016-10-10 20:24:56

标签: android android-service android-notifications android-broadcastreceiver ondestroy

所以,我有一个onDestory()看起来像这样的服务:

@Override
public void onDestroy() {
    super.onDestroy();
    stopLocationUpdates();
    googleApiClient.disconnect();
    Foreground.get(this).removeListener(this);
    // Here I have some code which sets shared preferences values
    phoneDataManager.markLastLocation();
    toastHandler.post(new Runnable() {

        @Override
        public void run() {
            Toast.makeText(getApplicationContext(), "service onDestroy", Toast.LENGTH_SHORT).show();
        }
    });
}

正如您所看到的,我在这里有很多事情要做(断开和停止位置更新,在SQLite数据库中进行一些更改,并设置一些SharedPreferences值。

根据我的阅读,onDestory无法保证被调用。我看到它没有被调用的一个场景是 -

运行服务 - >关闭申请(从应用列表中删除) - >我使用service.startForeground(1, notification);将服务带到前台,通知显示 - >点击通知操作会触发BroadcastReceiver

public class ServiceShutDownReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent serviceIntent = new Intent(context.getApplicationContext(), LocationService.class);
        context.stopService(serviceIntent);
    }

}

context.stopService(serviceIntent); 致电onDestory,但不会被调用 - >所以onDestory中的所有代码都没有被执行。

此问题的最佳做法是什么?理想情况下,我希望在服务停止时调用一段保证的代码。

1 个答案:

答案 0 :(得分:1)

通常,您不应该关注未调用onDestroy()的情况,因为这意味着系统会强制并立即销毁服务(及其所有相关资源和本地变量,保留在内存中)。

建议始终在此放置释放持久处理程序的代码,如MediaPlayer,BroadcastReceiver,GPS位置更新等。这是一种很好的做法,可以处理90%正常停止服务的情况。

但是,如果要实现一些自定义的“最后一分钟检查”,那么系统可能永远不会调用此方法,并且永远不会执行此代码。您的开发策略应该遵循这种模式,不应该依赖于此,因为没有其他可靠的方法可以知道服务即将被销毁。

作为最后的手段,您可以监听Application::onLowMemory()回调,当系统内存不足并且接近启动查杀过程时会触发回调,但即使这样也不是100%保证。