在我正在开发的应用程序中,我有一个在循环中运行的线程。在循环内部,会评估几个条件,并且取决于这些条件,一个或另一个值存储在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。
我该怎么办?
由于
答案 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
}
}