Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 确定服务实例是否正在运行并终止它_Java_Android - Fatal编程技术网

Java 确定服务实例是否正在运行并终止它

Java 确定服务实例是否正在运行并终止它,java,android,Java,Android,我有一个Android服务,比如说“Service.java” 我启动一个实例,并向我启动的服务的每个实例传递一个唯一的id(这样我就不会有两个uid相同的服务同时运行): 假设我在“Service.java”中为这个uid设置了一个变量: private String uid; @Override public int onStartCommand(Intent intent, int flags, final int startId) { super.onStartCommand(i

我有一个Android服务,比如说“Service.java”

我启动一个实例,并向我启动的服务的每个实例传递一个唯一的id(这样我就不会有两个uid相同的服务同时运行):

假设我在“Service.java”中为这个uid设置了一个变量:

private String uid;
@Override
public int onStartCommand(Intent intent, int flags, final int startId) {
    super.onStartCommand(intent, flags, startId);

    if(intent != null) {
        Bundle infoBundle = intent.getExtras();
        this.uid = infoBundle.getString("KEY");
    }

    ...
}

public String getUid() { return this.uid; }
有没有办法检查“Service.java”的实例是否使用给定的uid运行并杀死它

我有一个键/值对列表,我希望在一天中的特定时间启动此服务的实例,但是如果用户“禁用”某个时间段(键/值对),我希望服务停止

背景故事:

我有一个应用程序,它在给定的轮询数据源更改的时间前30分钟启动服务。数据馈送不再可用后,服务自行终止

如果用户在这个时间段(key/value pair-uid)中“取消/禁用”,我不希望服务在接下来的30分钟内运行,所以我想在“取消/禁用”后立即终止它

我可能走错了方向


无论哪种方式,都非常感谢您的输入,谢谢

我认为这更像是:您的服务需要知道数据模型何时更改。在这种情况下,数据模型是“键/值对列表”,每个都具有启用/禁用状态

假设这是存储在数据库、
SharedReferences
或一个文件中,并带有一个用于快速访问的单例缓存,则有三种选择可让服务了解数据模型更改:

  • 使用事件总线或其他侦听器模式,这样,如果服务存在,它就会发现更改,并可以采取一些适当的步骤。如果您的服务在单独的进程中运行,则事件总线必须是系统级广播(与
    LocalBroadcastManager
    相反,后者是进程内事件总线)

  • 使用
    ContentProvider
    前置数据模型,并使用
    ContentObserver
    通知更改(这就像用别克拍苍蝇一样,但是,嘿,这是一个选项)

  • 更改数据模型时,使用一些信息(例如,自定义操作字符串)调用
    startService()
    ,让服务知道这是一个“检查数据模型”事件。这种方法的缺点是,如果服务还没有启动,那么您就启动它,尽管服务可能会意识到如果没有什么事情要做,就立即停止自己

  • 就我个人而言,我会选择选项1


    但是,回到您的字面问题,按需从服务中提取数据的唯一好方法是使用绑定模式,其中您的客户端通过
    bindService()
    连接到服务,服务以
    绑定器的形式发布API。这与您当前的方法并不相互排斥。但是,这种方法的缺点类似于上面的#3:如果服务尚未运行,尝试绑定到它的行为将创建服务的实例


    没有什么能阻止您采用“哦,服务是单例的,所以我将通过一些
    静态
    字段某处”的方法来跟踪它的状态。我甚至偶尔也会在废弃应用程序中这样做,尽管这让我感到恶心。它也只适用于与应用程序其余部分处于相同流程的服务;如果您的服务处于单独的流程中,则此方法不起作用。

    根据文档

    请求启动给定的应用程序服务。意图可以 包含特定服务的完整类名 要启动的实现,或通过操作的抽象定义 和其他领域的那种服务开始。如果这项服务是 尚未运行,它将被实例化并启动(创建 如有需要,为其制定流程);如果它正在运行,则它将保持运行状态

    但是如果您使用的是startService()

    您应该指定何时停止服务中的服务

    此外,您还应该知道服务将在主线程(阻止主线程)上运行,除非您在服务中启动一个新线程,或者使用一个IntentService,该IntentService使用一个辅助线程依次处理每个Intent,并在其用完时自行停止

    您可以有一个线程池实现。有一个作业队列,在你把任何东西放入队列之前,你可以检查它是否已经存在

    您可以将这些作业设置为可运行,并为每个作业设置UUid。你可以移除它们,打断它们做任何你喜欢的事情


    这里有一个复杂但工作很好的例子:)

    谢谢您的回复@commonware我想我的主要问题是,我一直想在“onClick”事件中立即终止服务。如果我进行onClick更新SharedReferences,并且该服务(每分钟执行一项任务)检查SharedReferences,以确定该服务是否被视为“收藏夹”,我可以使该服务继续工作(如果它仍然处于启用状态)或自杀(如果它已被禁用)。
    private String uid;
    @Override
    public int onStartCommand(Intent intent, int flags, final int startId) {
        super.onStartCommand(intent, flags, startId);
    
        if(intent != null) {
            Bundle infoBundle = intent.getExtras();
            this.uid = infoBundle.getString("KEY");
        }
    
        ...
    }
    
    public String getUid() { return this.uid; }