如何在按下布局中的按钮时停止服务

时间:2016-08-27 20:46:07

标签: android android-studio android-service

我有一个服务,每隔几秒运行一次,然后睡觉,直到经过一段时间。不理想,但对我的目的有效。我想在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)似乎无效,所以我该怎么做。

谢谢!

3 个答案:

答案 0 :(得分:2)

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

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
    }
}

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

MyService.shouldContinue = false;

答案 1 :(得分:1)

onHandleIntent()中您有以下代码:

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

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

这将永远不会停止运行,因为没有什么可以阻止它运行。 IntentService已启动一个工作线程,此工作线程已调用onHandleIntent()。即使你打电话给stopService(),也没有什么可以阻止正在运行的工人线程。

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

您应该使用常规Service并覆盖onStartCommand()。在onStartCommand()中,只需创建Handler并发布符合您需要的Runnable即可。在Runnable结束时,Runnable可以使用Handler将自己发布到postDelayed()Runnable会在一定延迟后再次运行stopService()(而不是onDestroy()睡觉的线程)。当您致电Service时,removeCallbacks()会调用Runnable,您应致电 <?php $args = array( 'posts_per_page' => 5, 'offset' => 0, 'category_name' => 'featured', 'orderby' => 'date', 'order' => 'DESC', 'post_type' => 'product', 'post_status' => 'publish' ); $posts_array = get_posts( $args ); ?> 以阻止include ("db_conection.php"); if (isset ( $_GET ['view'] )) { $view_id = $_GET ['view']; $query_run = null; $query1 = "SELECT * FROM question where testid ='" . $view_id . "'"; $run = mysqli_query ( $conn, $query1 ); // here run the sql query. while ( $row = mysqli_fetch_array ( $run ) ) { echo ' <tr> <td>' . $row ['qid'] . '</td> <td>' . $row 'testid'] . '</td> <td>' . $row ['questions'] . '</td> <td> <a href="remove_question.php?del=' . $row ['qid'] . '" class = "btn btn-danger btn-block">Delete</a> </td> </tr> '; } } if (isset ( $_GET ['del'] )) { $delete_id = $_GET ['del']; $delete_query = "Delete from question WHERE qid='".$delete_id."'"; // delete // query // $run=mysqli_query($conn,$delete_query); $run = $conn->query ( $delete_query ); if ($run) { // bootstrap class to open in the same window /* * echo "<script>window.open('Admin Delete * member.php','_self')</script>"; */ echo "<script>window.open('remove_question.php','_self')</script>"; echo '<div align = "center" style = "margin-top:10px;" class = "alert alert-success">deleted...</div>'; } else { echo "deletion field"; } } 再次投放。

答案 2 :(得分:0)

  

不理想,但对我的目的有效。

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

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

确保您建议的真正what the user will want

  

这基本上是我在NotifService中所拥有的:

IntentService并非旨在让您无限期地绑定其主题。这就是您在使用stopService()停止播放时遇到问题的原因。

  

我现在如何停止服务?

您将使用您自己的Service子类替换该服务,并使用您自己的线程在onStartCommand()中启动。您的用户界面会调用stopService(),而在onDestroy()中,您可以通过某种方式终止该线程。

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