简体   繁体   English

如何向处理程序发送中断以中断Thread.sleep()?

[英]How do I send an interrupt to a handler to break a Thread.sleep()?

I have a Handler that is inside a Service and I block this thread until the user chooses to stop the service. 我在服务内部有一个处理程序,并且我阻塞了该线程,直到用户选择停止服务为止。 To make it less CPU intensive I am trying to use Thread.sleep() and repeat checking the blocking condition after an interval of 10 minutes . 为了减少对CPU的占用,我尝试使用Thread.sleep()并在间隔10 minutes后重复检​​查阻塞情况。 Here's my implementation of my handlemessage : 这是我的handlemessage的实现:

@Override
public void handleMessage(Message msg) {
    Log.e("Service", "looper started");
    GPSThread gp=new GPSThread(getApplicationContext());
    gp.start();         
    ModeController mc=new ModeController(getApplicationContext());
    mc.start();
    NetworkSniffer nh=new NetworkSniffer(getApplicationContext());
    nh.start();
    while(stopService)    //stopService is a volatile boolean i use to block until user opts to stop the service
    {                   
        try {
            Thread.sleep(10*60*1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
                e.printStackTrace();
        }               
    }    
    mc.stopThread();
    gp.stopThread();
    nh.stopNetworkThread();
    stopSelf(msg.arg1);
}

Now my problem is that if I change the value of stopService to false (through a public function) it might take upto 10 minutes to quit the while loop. 现在我的问题是,如果我通过公共函数将stopService的值更改为false,则可能需要10分钟才能退出while循环。 If it were a thread I would have used a Thread.interrupt() and quit the while loop. 如果它是一个线程,我将使用Thread.interrupt()并退出while循环。

So my question is how do I achieve a similar thing for Handler ie, how to throw a InterruptedException for Thread.sleep() inside a Handler. 所以我的问题是我如何为Handler实现类似的目标,即如何在Handler中为Thread.sleep()抛出InterruptedException。

If it were a thread I would have used a Thread.interrupt() and quit the while loop. 如果它是一个线程,我将使用Thread.interrupt()并退出while循环。

Actually, the code >>is<< running on a thread, so you if you could work out what that thread is, you could interrupt it. 实际上,代码>> is <<在线程上运行,因此,如果可以弄清楚该线程是什么,就可以中断它。

Putting that aside, the way that you should do this is to have the code where you would have tried to interrupt the thread call Service.stopService . 撇开这一点,您应该这样做的方法是将代码放在您试图中断线程调用Service.stopService

References: 参考文献:

This approach works when the thread that is sleeping is the service's handler thread. 当正在休眠的线程是服务的处理程序线程时,此方法有效。 If you have explicitly created the thread yourself, then you will need to keep track of the thread our created and use Thread.interrupt on it. 如果您自己显式创建了线程,则需要跟踪我们创建的线程并在其上使用Thread.interrupt (And you could use the Thread.interrupted state rather than a custom stopService flag.) (并且您可以使用Thread.interrupted状态而不是自定义stopService标志。)

However, a better idea would be to avoid the sleep loop: https://stackoverflow.com/a/845291/139985 但是,更好的主意是避免sleep循环: https : //stackoverflow.com/a/845291/139985

Thanks to @Stephen C finally got it to work. 感谢@Stephen C终于使它能够工作。 Posting my code in the hope that it might help others in the future : 发布我的代码,希望将来对其他人有帮助:

package com.example.userpc.roadtracker;


import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.util.Log;

/**
 * Created by USER PC on 5/21/2016.
 */
public class MainServiceThread extends Service {

    private Looper mServiceLooper;
    private ServiceHandler mServiceHandler;
    private volatile static boolean stopService=true;
    private static HandlerThread mThread;

    public static void stopServiceThread()
    {
        stopService=false;
        mThread.interrupt();
    }

    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }
        @Override
        public void handleMessage(Message msg) {
            Log.e("Service", "looper started");
            GPSThread gp=new GPSThread(getApplicationContext());
            gp.start();         
            ModeController mc=new ModeController(getApplicationContext());
            mc.start();
            NetworkSniffer nh=new NetworkSniffer(getApplicationContext());
            nh.start();
            while(stopService)
            {                   
                try {
                    Thread.sleep(10*60*1000);

                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }               
            }    
            mc.stopThread();
            gp.stopThread();
            nh.stopNetworkThread();
            stopSelf(msg.arg1);
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        Log.e("Service", "in onCreate");
        stopService=true;
        HandlerThread thread = new HandlerThread("ServiceStartArguments",
                Process.THREAD_PRIORITY_BACKGROUND);
        mThread=thread;
        thread.start();
        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("Service","Started");
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        mServiceHandler.sendMessage(msg);
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mThread=null;
        Log.e("Service","Destroyed");
    }


}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM