5

プロジェクトにはいくつかのActivityサブクラスがあり、それぞれがSOAPベースのWebサービスを呼び出し、結果を処理して表示します。SOAPシリアル化、呼び出し処理、および結果のさまざまなPOJOオブジェクトへの解析は、MyWebServiceクラスにカプセル化されます。このクラスは、AsyncTaskを介して実際のWebサービス呼び出しを実行します。

結果を呼び出し元のActivityサブクラスに戻すことができるようにするために、これらすべてのアクティビティーがWebServiceResultProcessorインターフェースを実装し、onPostExecuteから呼び出されるAsyncTaskのコールバックとして機能する単一の関数(processWebServiceResults)を定義する必要があると考えました。

また、Webサービスの呼び出し中にProgressDialogを表示したいと思います。そして、ここに私の質問があります。ProgressDialog(MyWebServiceまたはそのAsyncTaskのいずれかから)を表示できるようにするには、呼び出し元のアクティビティのコンテキストへの参照を渡す必要があります。また、AsyncTaskからコールバック関数を実行できるようにするには、同じオブジェクト参照を渡す必要がありますが、今回はWebServiceResultProcessorとして渡します。これは私にはコードの臭いのようで、同じオブジェクトを2回渡しますが、それを回避する方法はわかりません。インターフェースの代わりに、新しい基本クラスを作成して、Activityクラスを拡張し、拡張クラスからの継承を強制することもできますが、これは、ListActivityなどをこのMyWebServiceクラスの使用から除外することを意味します。

これを行うためのより良い方法はありますか?

4

3 に答える 3

4

+1、いい質問です!

これはあなたの質問に対する直接的な答えではありません。AsyncTaskただし、そのようなものには正しい選択ではないと思います。私がそう思うのは、この場合AsyncTaskは への参照を保持しているからです(インスタンスまたは から呼び出されるコールバックをActivity介して)。ProgressDialogonPostExecute()

想像してみてください: Android では、OS が を実行するActivity前に. もちろん、これはある種のまれなケースですが、不可能ではありません。シナリオを考えてみましょう: ユーザーが電話を受け、あなたのアクティビティが見えなくなり、OS がさらに RAM を必要とするため、あなたのアクティビティを強制終了することを決定します。少なくともメモリリークのケース。AsyncTaskdoInBackground()

UIをバックグラウンドタスクから適切に分離する方法に関する情報をGoogleが文字通り非表示にしている理由がわかりません。はい、彼らは「サービスを使用する」と言います。しかし、それは些細な仕事ではありません。残念なことに、Google はほぼすべての開発トピックに優れたガイドを提供していますが、このトピックについては提供していません。それでも、「Google I/O 2010 - Android REST クライアント アプリケーション」のプレゼンテーションを参照して、インスピレーションを得ることをお勧めします。Androidでそのようなことを行う方法について鍵を与えたようです。

于 2012-06-20T07:36:06.257 に答える
3

AsyncTaskLoader を使用して Web サービスを実装し、Service コンポーネントを使用して同じ Web サービスを実装するこのブログ記事 (パート 1およびパート 2 ) を参照してください。さらに、両方のアプローチの違いを示しており、この記事には興味深いコメントもあります。

于 2012-06-20T07:57:01.873 に答える
0

Arhimed の警告にもかかわらず、私は AsyncTask を使用することになりました。Web サービスを呼び出すすべてのアクティビティが、呼び出された AsyncTask に をonDestroy()送信するようにします。cancel()AsyncTask の実装自体は、必要に応じて isCancelled() をチェックすることで、キャンセル リクエストを適切に処理します。

元の質問に関しては、私は過ちを犯したに違いありません - 解決策は本当に簡単です。Activity サブクラスのインスタンスを Object として AsyncTask に渡し、必要に応じて Context または WebServiceResultProcessor にキャストします。それがどのように機能するかを示すフラグメント:

if (callerActivity instanceof Context) {
    ProgressDialog dialog = new ProgressDialog((Context)callerActivity);
}

...

if (callerActivity instanceof WebServiceResultProcessor) {
    ((WebServiceResultProcessor)callerActivity).processWebServiceResults(soapObject);
}
于 2012-06-21T23:59:54.270 に答える