2012-08-08 9 views
7

AndroidアプリのサービスクラスでREST WebServiceを呼び出すと、NetworkOnMainThreadExceptionが作成されます。Android:サービスでネットワークを使用する

私はこの例外がアクティビティで発生する理由を理解しています:ネットワーク上で何かを同期的にフェッチすることは非常に悪いことですが、サービスクラスで同じエラーが発生するのは驚きです。 私の質問は次のとおりです。

この特定のケースでは、StrictMode.setThreadPolicy()を使用してこの呼び出しを許可する必要があります。 (そして、彼らが活動にこのエラーが発生したので、これを読んでいるもののために、AsyncTaskを使用して、このエラーを非表示にするStrictModeを使用していない)

-or私はAsyncTaskを使用する必要がありますか?その場合、ここで問題は何ですか?スレッドのサービスがアクティビティのサービスから分離されていませんか?

答えて

12

Serviceはバックグラウンド処理用ですが、メインスレッドで実行されます。

documentationからの短い引用:

注意:サービスは、デフォルトでは、それが宣言されているアプリケーションと同じプロセスで、そのアプリケーションのメインスレッドで実行されます。そのため、ユーザーが同じアプリケーションのアクティビティとやりとりしている間にサービスが集中的またはブロック動作を実行した場合、そのサービスはアクティビティのパフォーマンスを低下させます。アプリケーションのパフォーマンスに影響を与えないようにするには、サービス内で新しいスレッドを開始する必要があります。

「バックグラウンド処理」とは、サービスにユーザーインターフェイスがなく、ユーザーがアプリケーションと直接対話していなくても実行できることを意味します。しかし、バックグラウンド処理はすべてデフォルトでメインスレッドで行われます。

これを解決して例外を取り除くにはどうすればいいですか?ドキュメントには、バックグラウンドスレッドを使用する必要があることが示唆されています。あなたのサービスでは、AsyncTaskを使用するか、直接スレッドを作成することができます。しかし、私はあなたの場合にはIntentServiceが最適かもしれないと思います。 IntentServiceは、バックグラウンドスレッドでリクエストを処理します(これが、探していたサービスの種類です)。

+0

あなたの答えをありがとう、それは私が疑うものです。私はそれらがバックグラウンドタスクのために使用されていると仮定していました。サービスはデフォルトで別のスレッドに置かれますが、そうではありません。 実際に私は 'MediaPlayer'への呼び出しを管理するためにそのサービスを使用していますので、 'prepareAsync()'を使用すると、その動作をエレガントに管理できるため、メインスレッド上で問題を起こすようなことはありません。 ストリーミングURLを取得するために 'AsyncTask'を使用するには、サービスを変更するだけです。 – Teovald

+1

幸いですが、あなたのアプリが最適化されていることを確認するために、ネットワークを効率的に使用する方法を理解するのに役立つ資料もあります。 http://developer.att.com/developer/forward.jsp?passedItemId=7200042 –

関連する問題