5

私のプロジェクトには、SOAPベースのWebサービスを呼び出し、結果を処理して表示する、いくつかのアクティビティサブクラスがあります。 SOAPシリアル化、コール処理、およびさまざまなPOJOオブジェクトへの結果の解析は、MyWebServiceクラスにカプセル化されています。このクラスは、AsyncTaskを介して実際のWebサービス呼び出しを実行します。いくつかのアクティビティでAndroid AsnycTaskを再利用するためのパターン?

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

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

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

+0

あなたWebServiceResultProcessorは、コンテキスト/動作を拡張していますか? –

+0

@HeikoRuppいいえ、私はおそらくそれをそのままにしたいと思うでしょう。 –

答えて

0

Arhimedの警告にもかかわらず、私はAsyncTaskを使用して終了しましたが、これはまだ私の目的に合っています。私は、Webサービスを呼び出すすべてのアクティビティ(onDestroy())が呼び出されたAsyncTaskに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); 
} 
+1

if(callerActivity instanceof Context){..} 'が冗長チェックであると思います。あなたのケースで 'callerActivity'が何も見つからない限り、常に' Context'のインスタンスになるので、あなたは直接プログレス生成コードを呼び出すことができます。 –

4

+1、いい質問です!

これはあなたの質問に直接答えはありません。しかし、私はAsyncTaskがそのようなもののための正しい選択ではないと私に言わせてください。この場合、AsyncTaskActivityProgressDialogインスタンスまたはonPostExecute()からコールされるコールバック経由)への参照を保持しているからだと思います。

Androidの場合、OSはAsyncTaskdoInBackground()になる前にActivityを殺す可能性があります。これはもちろんコーナーケースのようなものですが、不可能ではありません。シナリオを考えてみましょう:ユーザーが着信コールを受信し、アクティビティが見えなくなり、OSがさらにRAMを必要とするため、アクティビティを停止することにします。少なくともメモリリークの場合。

私は、UIがバックグラウンドタスクから適切に分離される方法に関する情報を文字通り隠す理由は知らない。はい、彼らは「サービスを使う」と言います。しかし、それは簡単なことではありません。 Googleがほぼすべての開発トピックに素晴らしいガイドを提供するのは残念ですが、このガイドラインではありません。それでも、 "Google I/O 2010 - Android REST client applications"のプレゼンテーションでインスピレーションを確認することをお勧めします。彼らはAndroidでこのようなことをどうやってやるべきかの鍵を貰ったようだ。

+0

AsyncTask内からContextリファレンスを使用して危険を指摘してくれてありがとう。私はこれを非常に広範囲にカバーするhttp://stackoverflow.com/questions/3357477/is-asynctask-really-conceptually-flawed-or-am-i--missing-something質問と回答を見つけました。 –

+0

@AndrásSzepesházi:ありがとう、いい話です。しかし、ほとんどの場合、回避策の設定変更(デバイスのローテーションでのアクティビティの再起動など)の方法について説明しています。しかし、リモート・サーバ上に新しいユーザ・アカウントを作成するasynctaskがあるときに、私が記述したシナリオ(着信コール)内でアクティビティが強制終了されるとどうなりますか? :)アカウントは作成されますが、ユーザーがアクティビティに戻ると、asynctaskの結果は決して分かりません。ユーザーは再試行し、「このようなユーザー名は既に使用されています」というエラーが表示されますか? :) asycntaskが支払いトランザクションをしたらどうでしょうか? :) –

+0

うわーこれは悪です。サービスとハンドラの使用を避けたいと思っていましたが、これが唯一の方法だと思われます。 –

3

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

関連する問題