1

在我正在开发的应用程序中,我有一个循环运行的线程。在循环内部,会评估几个条件,并根据这些条件,将一个值或另一个值存储在 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。那没问题。

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

我能做些什么?

谢谢

4

3 回答 3

1

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

您可以使用editor.apply()而不是editor.commit()

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

与将其首选项同步写入持久存储的 commit() 不同,apply() 会立即将其更改提交到内存中的 SharedPreferences,但会开始异步提交到磁盘,并且不会通知您任何失败。如果此 SharedPreferences 上的另一个编辑器在 apply() 仍然未完成时执行常规 commit(),则 commit() 将阻塞,直到所有异步提交以及提交本身都完成。

于 2014-03-11T09:37:38.783 回答
0

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

其次,如果线程被中断:

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

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

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

于 2012-06-28T15:32:24.637 回答
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
}
}
于 2012-06-28T17:06:53.110 回答