【问题标题】:How do I send an interrupt to a handler to break a Thread.sleep()?如何向处理程序发送中断以中断 Thread.sleep()?
【发布时间】:2016-05-26 21:54:53
【问题描述】:

我有一个位于服务内部的处理程序,我阻塞了这个线程,直到用户选择停止服务。为了减少 CPU 密集度,我尝试使用 Thread.sleep() 并在间隔 10 minutes 后重复检查阻塞条件。这是我的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);
}

现在我的问题是,如果我将 stopService 的值更改为 false(通过公共函数),可能需要 10 分钟才能退出 while 循环。如果它是一个线程,我会使用 Thread.interrupt() 并退出 while 循环。

所以我的问题是如何为 Handler 实现类似的事情,即如何在 Handler 中为 Thread.sleep() 抛出 InterruptedException。

【问题讨论】:

    标签: java android multithreading thread-sleep android-handler


    【解决方案1】:

    如果它是一个线程,我会使用 Thread.interrupt() 并退出 while 循环。

    实际上,代码>>是

    抛开这一点,您应该这样做的方式是在您试图中断线程调用Service.stopService 的位置添加代码。

    参考资料:

    当处于休眠状态的线程是服务的处理程序线程时,此方法有效。如果您自己明确创建了线程,那么您将需要跟踪我们创建的线程并在其上使用Thread.interrupt。 (您可以使用Thread.interrupted 状态而不是自定义stopService 标志。)

    但是,更好的办法是避免 sleep 循环:https://stackoverflow.com/a/845291/139985

    【讨论】:

    • 非常感谢您提供的链接,先生,我正在浏览它们。我只是没有得到一件事。你说如果我能解决这个线程,我可以调用它的中断。先生,我该如何解决?
    • 这可能会很困难。 (在经典的 Java 世界中,您可能会使用 ThreadGroup 层次结构并按名称查找线程。但这是个坏主意。)如果您不能使用 serviceStop,那么最好的办法是将线程引用记录在某个变量中...
    • 谢谢大佬,终于搞定了。我从使用HandlerThread thread = new HandlerThread("ServiceStartArguments",Process.THREAD_PRIORITY_BACKGROUND); 的HandlerThread 对象中获得了Thread 实例。最后我在stopServiceMethod() 中调用了这个线程变量的中断。
    【解决方案2】:

    感谢@Stephen C 终于让它工作了。发布我的代码,希望将来可以帮助其他人:

    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");
        }
    
    
    }
    

    【讨论】:

      猜你喜欢
      • 2011-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 2013-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多