如何正确停止前台服务?

MMa*_*udi 9 service android foreground-service

我使用 startForeground 使我的服务在后台“持久化”而不会被操作系统杀死。
我通过调用 stopForeground 和 stopService 删除了主活动 onDestroy 方法中的服务。问题是,当我从最近的应用程序中清除我的应用程序以杀死它时,调试会话仍在运行,而在“正常”功能(不使用 startForeground)中,调试会话正确终止。
使用 adb shell 确认应用程序仍在运行。
startForeground 以某种方式创建了一个无法通过简单地停止前台和服务来停止的“特殊”运行线程。
请问有什么想法吗?

Has*_*eyd 21

如果要在从最近的任务中清除应用程序时停止服务,则必须stopWithTask在清单文件中为服务定义一个属性,如下所示

  <service
    android:enabled="true"
    android:name=".ExampleService"
    android:exported="false"
    android:stopWithTask="true" />
Run Code Online (Sandbox Code Playgroud)

那么你可以覆盖服务中的 onTaskRemoved 方法,这将在应用程序的任务被清除时调用

@Override
    public void onTaskRemoved(Intent rootIntent) {
        System.out.println("onTaskRemoved called");
        super.onTaskRemoved(rootIntent);
        //do something you want
        //stop service
        this.stopSelf();
    }
Run Code Online (Sandbox Code Playgroud)

  • 当心!根据文档,如果您在清单中设置了“stopWithTask=true”,则不会调用“onTaskRemoved()”(https://developer.android.com/reference/android/app/Service#onTaskRemoved(android.content 。意图)) (3认同)

Ale*_*das 5

我不知道它是否正确,但在我的应用程序中,我在这里停止了前台服务并且它可以工作。检查代码

private void stopForegroundService() {

    // Stop foreground service and remove the notification.
    stopForeground(true);

    // Stop the foreground service.
    stopSelf();
}
Run Code Online (Sandbox Code Playgroud)

更新

stopservice以某种方式从您的主类调用(而不是从 onDestroy调用),如下所示:

    Intent intent = new Intent(this, MyForeGroundService.class);
    intent.setAction(MyForeGroundService.ACTION_STOP_FOREGROUND_SERVICE);
    startService(intent);
Run Code Online (Sandbox Code Playgroud)

MyForegroundService.java

 private static final String TAG_FOREGROUND_SERVICE = "FOREGROUND_SERVICE";

public static final String ACTION_START_FOREGROUND_SERVICE = "ACTION_START_FOREGROUND_SERVICE";

public static final String ACTION_STOP_FOREGROUND_SERVICE = "ACTION_STOP_FOREGROUND_SERVICE";

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) {
            String action = intent.getAction();

            switch (action) {
                case ACTION_START_FOREGROUND_SERVICE:
                    startForegroundService();
                    break;
                case ACTION_STOP_FOREGROUND_SERVICE:

                    stopForegroundService();
                    break;
            }
        }
        return START_STICKY;
    }

  private void stopForegroundService() {
    Log.d(TAG_FOREGROUND_SERVICE, "Stop foreground service.");

    // Stop foreground service and remove the notification.
    stopForeground(true);

    // Stop the foreground service.
    stopSelf();
}
Run Code Online (Sandbox Code Playgroud)