1. ホーム
  2. android

[解決済み] SharedPreferencesへのアクセスはUIスレッドから行うべきですか?

2022-07-25 18:14:41

質問

Gingerbread のリリースに伴い、私はいくつかの新しい API を試しています。そのうちの 1 つが StrictMode .

私は、警告のひとつが getSharedPreferences() .

これは警告です。

StrictMode policy violation; ~duration=1949 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=23 violation=2

に対して与えられていて、それが getSharedPreferences() の呼び出しが UI スレッドで行われています。

べきである SharedPreferences のアクセスや変更は、本当に UI スレッドから行うべきなのでしょうか?

どのように解決するのですか?

もう遊んでくれているんですね!

いくつか注意することがあります。 (ダラダラとした箇条書きの形で)

  • もしこれが最悪の問題であれば、あなたのアプリはおそらく良い場所にあるのでしょう。) しかし、書き込みは一般に読み込みよりも遅いので、commit() の代わりに SharedPreferenced$Editor.apply() を使用していることを確認してください。apply() は GB で新しく、非同期です (しかし常に安全で、ライフサイクル遷移に注意)。 リフレクションを使って、GB+ではapply()を、Froyo以下ではcommit()を条件付きで呼び出すことができます。 この方法については、サンプルコードをブログポストで紹介する予定です。

ロードに関してですが...。

  • 一度ロードされると、SharedPreferences はシングルトンであり、プロセス全体にキャッシュされます。したがって、できるだけ早くロードして、必要な前にメモリ内に持っておきたいのです。 (SharedPreferences を使用している場合、単純な XML ファイルであるため、小さいと仮定します...) 将来、ユーザーがボタンをクリックしたときに不具合が発生しないようにしたいものです。

  • が、context.getSharedPreferences(...)を呼び出すたびに、バッキングXMLファイルが変更されたかどうかを確認するために統計されるので、とにかくUIイベント中にそれらの統計を避けたいと思うでしょう。 統計は通常高速であるべきですが(そしてしばしばキャッシュされます)、yaffsは同時並行性という点ではあまり優れていません(そして多くのAndroidデバイスはyaffs上で動作します... Droid、Nexus Oneなど)ので、ディスクを避けるなら、他の飛行中または保留中のディスク操作の後ろに引っかかるのを避けることができます。

  • したがって、おそらく onCreate() 中に SharedPreferences をロードし、stat を回避して同じインスタンスを再使用したいと思うことでしょう。

  • しかし、onCreate() 中にとにかく設定を必要としない場合、その読み込み時間はアプリの起動を不必要に遅らせるので、一般的には FutureTask<SharedPreferences> サブクラスのように新しいスレッドをキックオフして FutureTask サブクラスの値を .set() するものを持つ方がよいでしょう。 そして、必要な時にFutureTask<SharedPreferences>のメンバーを調べて、.get()すればいいだけです。 私は、Honeycombの舞台裏で、透過的にこれを自由にすることを計画しています。 この分野のベストプラクティスを示すいくつかのサンプルコードを公開しようと思います。 この分野でのベストプラクティスを示すいくつかのサンプルコードを公開しようと思います。

Android Developers ブログで、今後 1 週間以内に StrictMode 関連の記事が掲載される予定ですので、チェックしてみてください。