6

AsyncTask#doInBackground内でAndroidコンテキストを使用する場合、スレッドセーフですか?コンテキストは、コンストラクターを介して、または周囲のアクティビティからgetApplicationContext()を介して提供されます。この簡単な質問は、stackoverflowやその他の場所でよく聞かれますが、明確な答えが見つかりませんでしたか?

たとえば、doInBackground()では、DAOクラスをインスタンス化するためにコンテキストを使用します。

 @Override
 protected Void doInBackground(Void... params) {  

   ExampleDao dao = new ExampleDao(context);
   ...

 }

この方法でそれを行ういくつかの例を見ましたが、コンテキストがメイントレッド(UIスレッド)とワーカースレッドによってアクセスされるようになったため、これがスレッドセーフであるとは想像できません。

4

3 に答える 3

7

何かを変更せず、コンテキストを介してのみリソースを取得する限り、いつでも別のスレッドからコンテキストにアクセスできます。スレッドセーフに問題はありません。

問題は、スレッドが実行されている限り、コンテキストがメモリに残り、アクティブになることです。常に有効なコンテキストを持つことに依存できるため、これはあなたにとって良いことです。悪い点は、アクティビティをコンテキストとして渡すと、このアクティビティのすべてのビューとメンバー変数もメモリに残り、Waqasが提案したように、これにより大量のメモリのガベージコレクションが非常に遅くなる可能性があることです。

別のスレッドからは行わないこととして、現在表示されているビューに影響を与えるsetTheme()などのContextサブクラスからメソッドにアクセスします。

于 2012-05-15T11:01:52.507 に答える
2

ビューで何もする必要がない場合は、常にgetApplicationContext()アプリケーションのコンテキスト(アクティビティのコンテキストではない)を参照するものを使用してみてください。スレッド化や方向変更中のメモリリークを回避するのに役立つ場合があります。だから、私はそれがAsyncTaskのあなたのニーズにも合うと思います。

于 2012-05-15T10:35:38.470 に答える
1

コンテキストは実際にはスレッドセーフではありません。ただし、アプリケーションコンテキストのインスタンスを渡して、たとえばdbに書き込むことは問題ありません。

于 2012-05-15T10:36:01.040 に答える