在销毁活动后重新创建Android服务

时间:2017-03-01 22:14:38

标签: android sockets service background-process

首先,我正在创建必须在后台运行的应用程序(即使用户已杀死应用程序)。我有蓝牙服务器(raspberry pi),我的应用程序应该像该服务器的客户端。建立连接后,我需要保持活动状态,并且只有当用户太过舞台服务器或服务器发送特定的断开连接命令时才会断开连接。所以我只是找到了BluetoothChatExample并将所有代码从活动中提供给服务(因为我需要进行通信,即使用户杀死了应用程序,我的服务应该独立于我的主要活动)。

以下是我服务中的一些代码段

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开始我的服务但是当我从“最近使用的应用程序”列表中删除应用程序时,问题就出现了问题我即使onDestroy()onCreate没有调用!!!)然后再次调用START_NOT_STICKY并且服务从头开始。但是蓝牙通信基于套接字,因此它们也被重新创建,并且我的连接丢失了。我也试过了class UploadedFile < ActiveRecord::Base has_attached_file :file attr_accessor :file_url def file_url self.file.url(:original) if self.file end end UploadedFile.first.as_json(methods: [:file_url]) #Will work and will show the url in the json UploadedFile.all.as_json(methods: [:file_url]) #Will work and will show the url in the json UploadedFile.select('id', 'othertablecolumn').joins("JOINS SOMETING").where("SOME CONDITIONS").as_json(methods: [:file_url]) #Will not work and will show the missing url in the json 但是当我关闭我的应用程序并且从未重新创建时,我的服务就会被销毁。用户关闭我的应用程序后,是否可以保持服务活着(而不是重新创建)?

5 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

  

首先,我正在创建必须在后台运行的应用   (即使用户杀死了应用程序)。

除非您是系统应用程序,否则不是。 Android的应用程序模型非常明确,应用程序不能强迫自己连续运行,这是有充分理由的。如果您手机上的大量应用程序决定这样做会怎么样?移动设备不是台式计算机。它们具有电池,并且在后台连续旋转的过程中无法实现合理的电池寿命。为了获得合理的电池寿命,Android依赖于能够在没有任何操作时让CPU进入睡眠状态。

此外,如果用户刷掉您的活动,该应用程序将处于非活动状态。这意味着它无法接收广播(包括警报管理器唤醒),并且只能由用户从启动器启动活动,启动您的某个活动的其他应用程序或在应用程序内启动服务的其他应用程序重新启动。对于新安装的应用程序也是如此:在您明确使用它们之前它们无法运行。

对于非系统应用,您可以做的最好的事情是使用startForeground() + START_STICKY。这是Android最强大的指标,您的服务很重要,不应该被杀死。

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

答案 3 :(得分:0)

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

Poco::Data::MySQL::Connector::registerConnector();

现在,您的服务将在独立流程上运行,而非初始应用流程。

答案 4 :(得分:0)

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

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

哦,如果您想在Android Studio中看到此消息,请确保将Android Monitor logcat设置为Verbose和No Filters。按照您的服务的类名过滤也会有所帮助,如下所示:

Android Studio logcat

再次,首先确保您的服务正在运行。如果你没有在清单中声明它,它就不会开始。