Java 在Android应用程序中多次调用Thread.interrupt,但我只调用一次
这个问题纯粹是出于好奇。我已经找到了一个解决办法,如果有人感兴趣,我会在问题的最后解释 我有一个运行后台线程的android应用程序。我想在用户按下电源键时中断此线程。为了实现这一点,我使用了如下广播接收器:Java 在Android应用程序中多次调用Thread.interrupt,但我只调用一次,java,android,multithreading,Java,Android,Multithreading,这个问题纯粹是出于好奇。我已经找到了一个解决办法,如果有人感兴趣,我会在问题的最后解释 我有一个运行后台线程的android应用程序。我想在用户按下电源键时中断此线程。为了实现这一点,我使用了如下广播接收器: public Class MyService extends Service { private MyThread myThread; //https://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-
public Class MyService extends Service {
private MyThread myThread;
//https://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/
private class ScreenReceiver extends BroadcastReceiver {
boolean wasScreenOn = true;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.d(TAG, "Power key!");
myThread.interrupt();
wasScreenOn = false;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
wasScreenOn = true;
}
}
}
private Class MyThread extends Thread {
private MyObject myObject;
//various thread functions
public void run(){
while(!isInterrupted()){
//I have code here that waits for the user to let us know to start
myObject = new MyObject();
myObject.foo();
}
}
}
public void onCreate(){
//various setup steps
myThread = new MyThread();
myThread.start(); //myThread.run() will get called by this
}
}
不幸的是,仅仅中断线程是不够的,因为它没有足够频繁地轮询中断:该线程包含一个运行函数foo的对象MyObject的实例,在foo完成之前,我无法轮询线程上的中断。为了解决这个问题,我在MyObject类中实现了一个标志,我可以在foo中检查该标志,并在必要时中断该函数,就像Thread.interrupt如何工作一样,除了MyObject不扩展Thread之外
public class MyObject {
//other variables
private boolean isInterrupted;
public MyObject(){
//various setup
isInterrupted = false;
}
public boolean foo() {
while(!isInterrupted){
//doStuff, return true or false if finished
}
return false;
}
public void setInterruptFlag(){
isInterrupted = true;
}
}
有了它,我覆盖了MyThread中的中断方法:
public void interrupt(){
Log.d(TAG, "Interrupted!");
if(myObject != null)
myObject.setInterruptFlag();
super.interrupt();
}
这将停止函数foo,并或多或少执行我想要的操作。但是,下次从myThread.run调用myObject.foo时,myThread.interrupt很早就被调用了,整个过程都停止了。之后的下一次跑步将恢复正常
查看日志输出,我只看到电源键!按预期关闭屏幕时打印输出。然而,电话中断了!打印输出快速连续出现4或5次,然后在用户重新启动线程时再次出现。我唯一调用myThread.interrupt的地方就是电源键的正下方!log语句,所以我不知道额外的调用来自哪里。系统是否在某些地方自动调用中断,如果是,原因是什么
我提到的解决方法是完全取消对myThread.interrupt的调用,而是扩展myObject的范围,这样我就可以直接从BroadcastReceiver调用myObject.setInterruptFlag了不一定是问题的解决方案,但在MyObject中的isInterrupted可能应该被声明为volatile。您是100%正确的。实际上,我目前正在研究如何使用锁来让isInterrupted表现得更好,所以如果你对此有任何建议,我会向他们敞开心扉。我个人的经验是不使用中断。太多的Java类调用中断以使其对应用程序可靠。使用您自己的中断类型字段。让它变得不稳定。这样,就不会对谁、为什么、什么时候有任何疑问。查看使用Thread.stop的替代解决方案。收到。