如何在按下布局中另一个 activity 的按钮时停止服务

How to stop a service when a button in the layout for another activity is pressed

我有一项服务每隔几秒运行一次,然后休眠直到特定时间过去。不理想,但对我的目的有效。我想在 NotifActivity 的布局中有一个按钮,可以根据要求启动和停止名为 NotifService 的服务。这基本上是我在 NotifService 中的内容:

public class NotifService extends IntentService {
public NotifService() {
    super("NotifService");
}

@Override
protected void onHandleIntent(Intent intent) {
    while(true){
        try {
            checkcalc();
            Thread.sleep(1000);

        } catch (InterruptedException e) {
            // Restore interrupt status.
            Thread.currentThread().interrupt();
        }
    }
}
 public void checkcalc () {
    //some code I am trying to run
}

public void notifSend(String num){

    //Sends a notification
    }
}

以及启动服务时调用的NotifActivity位:

public void sendNotification(View view) {
    Intent serviceIntent = new Intent(this, NotifService.class);
    startService(serviceIntent);

}

我现在如何停止服务? stopService(serviceIntent) 好像没效果,怎么办

谢谢!

这是一个简单的变通解决方案,它使用易失性静态变量并检查您服务中应检查服务继续的某些行中的继续条件:

class MyService extends IntentService {
public static volatile boolean shouldContinue = true;
public MyService() {
    super("My Service");
}

@Override
protected void onHandleIntent(Intent intent) {
    doStuff();
}

private void doStuff() {
    // do something 

    // check the condition
    if (shouldContinue == false) {
          stopSelf();
          return;
      }

     // continue doing something

     // check the condition
     if (shouldContinue == false) {
         stopSelf();
         return;
     }

        // put those checks wherever you need
    }
}

并在您的 activity 中执行此操作以停止您的服务,

MyService.shouldContinue = false;

Not ideal, but effective for my purposes.

在最好的情况下,您的代码将无法可靠地工作。例如,当设备进入睡眠模式时,它不会工作。

(最坏的情况是愤怒的用户和枪支)

确保你提出的确实what the user will want

Here is basically what I have in NotifService:

IntentService 不是为你无限期地占用它的线程而设计的。这就是为什么您在使用 stopService().

停止它时遇到问题

How would I now stop the service?

您将用您自己的 Service 子类和您自己的线程替换该服务,您在 onStartCommand() 中开始。您的 UI 会调用 stopService(),而在 onDestroy() 中,您通过某种方式终止该线程。

例如,如果您 used ScheduledExecutorService,而不是 Thread.sleep() 循环,onStartCommand() 将安排您的定期作业,而 onDestroy()shutdown() ScheduledExecutorService。您甚至不需要弄乱线程,因为 ScheduledExecutorService 为后台工作提供了线程。

onHandleIntent() 中你有这个代码:

while(true){
    try {
        checkcalc();
        Thread.sleep(1000);

    } catch (InterruptedException e) {
        // Restore interrupt status.
        Thread.currentThread().interrupt();
    }
}

这永远不会阻止 运行ning,因为没有什么可以阻止它从 运行ning 开始。 IntentService 已启动一个工作线程并且此工作线程已调用 onHandleIntent()。即使您调用 stopService(),也不会停止 运行ning 工作线程。

您的架构存在缺陷。 IntentService 不适用于此用途。当每次调用 onHandleIntent() 最终完成时,您应该使用 IntentService

您应该只使用常规 Service 并覆盖 onStartCommand()。在 onStartCommand() 中,只需创建一个 Handler 和 post 一个 Runnable 即可。在这个 Runnable 的末尾,Runnable 可以 post 使用 postDelayed() 本身到 Handler,这将 运行 Runnable 在一定的延迟后再次(而不是让线程休眠)。当您调用 stopService() 时,onDestroy() 将在 Service 中调用,您应该调用 removeCallbacks() 以再次停止来自 运行ning 的 Runnable