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.commit()の代わりにeditor.apply( ) を使用することもできます!

commit() の代わりに apply() が機能する理由は、戻り値を待つ必要がないため、新しいスレッドで I/O を実行するためです。

設定を永続ストレージに同期的に書き込む commit() とは異なり、apply() は変更をメモリ内の SharedPreferences にすぐにコミットしますが、ディスクへの非同期コミットを開始するため、失敗は通知されません。この SharedPreferences の別のエディターが通常の commit() を実行し、apply() がまだ未解決の場合、commit() はすべての非同期コミットとコミット自体が完了するまでブロックされます。

于 2014-03-11T09:37:38.783 に答える
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 に答える
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 に答える