提交明确的中断状态

时间:2012-06-28 15:24:13

标签: android multithreading sharedpreferences interrupt

在我正在开发的应用程序中,我有一个在循环中运行的线程。在循环内部,会评估几个条件,并且取决于这些条件,一个或另一个值存储在SharedPreferences中。

public void run()
{
  try
  {
    SharedPreferences preferences = 
       context.getSharedPreferences("MyPrefs", Activity.MODE_PRIVATE);

    SharedPreferences.Editor editor = preferences.edit();

    while (true)
    {                       
      if (condition1)
      {
        editor.putBoolean("mykey", "1");
      }
      else if (condition 2)
      {
        editor.putBoolean("mykey", "2");            
      }
      editor.commit();

      if (isInterrupted())
         throw new InterruptedException();              

      Thread.sleep(60000); // 60 seconds
    }
  }
  catch (InterruptedException e)
  {
    Thread.currentThread().interrupt();
  }
}

此线程由onResume方法中的Activity启动,并在onPause方法中被中断。

如果线程在休眠时被活动(主线程)中断,则抛出InterruptedException。没关系。

但我的问题是,如果活动(主线程)在线程运行时中断线程(而不是休眠)。 “interrupt flag”设置为true,但在编辑器上调用commit后,该标志设置为false,因此我无法中断线程抛出InterruptedException。

我该怎么办?

由于

3 个答案:

答案 0 :(得分:1)

我刚刚遇到同样的问题并找到了解决方案。

您可以使用editor.apply()代替editor.commit()

apply()工作而不是commit()的原因是它在新线程上执行I / O,因为它不需要等待返回值:

  

与commit()不同,后者将其首选项写入持久性   同步存储,apply()将其更改提交到内存中   SharedPreferences立即启动异步提交   磁盘,您不会收到任何故障通知。如果是其他编辑   这个SharedPreferences在apply()时执行常规commit()   仍然未完成,commit()将阻塞,直到所有异步提交为止   完成以及提交本身。

答案 1 :(得分:0)

首先,不要这样做:while (true)

其次,如果线程被中断:

if (isInterrupted())
         throw new InterruptedException();              

      Thread.sleep(60000); // 60 seconds
    }
  }
  catch (InterruptedException e)
  {
    Thread.currentThread().interrupt();
  }

它捕获中断然后再次中断线程。这会尖叫递归,而你的无限循环也没有帮助。

答案 2 :(得分:0)

调用editor.commit()将进行I / O.如果线程上有挂起的中断,则可能会中止I / O并清除挂起的中断。

为了做你想做的事,你可能需要防止线程在提交时被中断。您需要同步访问权限,以便应用程序只能在线程处于休眠状态时中断它。像这样:

// This method will interrupt the thread that is looping ONLY while it is sleeping
public synchronized void interruptNow() {
    threadThatIsLooping.interrupt();
}

public void run() {
try {
    SharedPreferences preferences = 
       context.getSharedPreferences("MyPrefs", Activity.MODE_PRIVATE);
    SharedPreferences.Editor editor = preferences.edit();
    while (true) {
        synchronized {
            // Cannot be interrupted within this block                  
            if (condition1) {
                editor.putBoolean("mykey", "1");
            } else if (condition 2) {
                editor.putBoolean("mykey", "2");            
            }
            editor.commit();
        }             
        Thread.sleep(60000); // 60 seconds
    }
} catch (InterruptedException e) {
    // Do whatever you want here when the thread is interrupted while sleeping
}
}