Android 销毁后重新创建服务 activity

Android Service is recreated after destroying activity

首先,我正在创建必须在后台运行的应用程序(即使用户终止了应用程序)。我有蓝牙服务器 (raspberry pi),我的应用程序应该像该服务器的客户端一样工作。建立连接后,我需要保持它的活动状态,并且仅当用户距离 prom 服务器太远或服务器发送特定的断开连接命令时才断开连接。所以我简单地找到了 BluetoothChatExample 并将所有代码从 activity 放到服务中(因为即使用户终止应用程序我也需要进行通信,我的服务应该独立于我的主要 activity)。

这是我的服务中的一些代码片段

public class BluetoothCommunicationService extends Service {
    public BluetoothCommunicationService() {

    }

    @Override
    public void onCreate() {
       super.onCreate();

   //....
   //....
   //....
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
       if(intent.getAction.equals("stop") {
           stopSelf();
       }
       return START_STICKY;
    }

private class AcceptThread extends Thread {
            //....
}

private class ConnectThread extends Thread {
    //....
}

private class ConnectedThread extends Thread {
    //....
}

@Override
    public void onDestroy() {
        super.onDestroy();

}

} 因此,正如您所看到的,我以 START_STICKY 的身份启动了我的服务,但是当我从 "recently used apps" 列表中终止应用程序时,我也终止了我的服务(即使 onDestroy() 是not called!!!) 然后再次调用 onCreate 并且服务从头开始。但是蓝牙通信是基于套接字的,所以它们也被重新创建并且我的连接丢失了。我也试过 START_NOT_STICKY 但是当我关闭我的应用程序时我的服务就会被破坏并且它永远不会重新创建。是否有可能在用户关闭我的应用程序后保持服务活动(而不是重新创建它)?

您不能保证该服务不会被杀死。它可以并且将在某个时候终止,关闭所有应用程序将破坏您的服务。 START_STICKY 的唯一好处是它稍后会尝试重新启动服务。

这是设计好的。当您在最近的应用程序中滑动一个应用程序时,它会杀死整个应用程序。这包括任何后台服务。

是的,可以让您的服务保持活动状态。您应该添加到清单中:

<service android:name=".BluetoothCommunicationService"
            android:process=":nameNewProcessThatYourServiceWillUseHere"/>

现在您的服务将在独立的进程上运行,而不是您的初始应用程序进程。

First of all I'm creating app that must be working in the background (even if user killed application).

除非您是系统应用程序,否则您不是。 Android 的应用程序模型非常清楚,应用程序不能强迫自己连续 运行,这是有充分理由的。如果 phone 上的大量应用决定这样做怎么办?移动设备不是台式电脑。它们有电池,并且无法在后台不断运行的进程中实现合理的电池寿命。为了获得合理的电池寿命,Android 取决于能够在没有任何事情发生时让 CPU 进入睡眠状态。

此外,如果用户将您的 activity 滑开,该应用程序将处于非活动状态。这意味着它无法接收广播(包括闹钟管理器唤醒),并且只能由用户从启动器启动您的 activity、另一个应用程序启动您的一个活动或另一个应用程序在其中启动服务来重新启动应用程序。对于新安装的应用程序也是如此:它们不能 运行 直到您明确使用它们。

对于非系统应用程序,最好使用 startForeground() + START_STICKY。这是 Android 表明您的服务很重要且不应被终止的最有力指标。

系统应用程序可以在其清单中声明自己是持久的,并且它们的进程永远不会被终止。除非你正在构建 Android dist 并自己刷新它,尽管这不是一个选项。

如果您的服务之前已经启动,返回 START_STICKY 或 START_REDELIVER_INTENT 并在清单中声明,则您的服务应该在一段时间后重新启动。 Android 将决定该时间并将其记录在监视器控制台中。它说的是这样的:

Scheduling restart of crashed service com.company.app/MyService in 1000ms

哦,如果您想在 Android Studio 中看到此消息,请确保将 Android 监视器 logcat 设置为详细且无过滤器。按服务的 class 名称过滤也会有所帮助,如下所示:

同样,首先确保您的服务是 运行。如果您不在清单中声明它,它将不会启动。