これはかなり一般的な問題だと思いますが、それでも満足のいく答えが見つからなかったので、自問してみます。
これはコードの一部です:
// this is insine OnClickView
TextView status = (TextView) findViewById(R.id.status);
status.setText("Trying to connect to the server...");
try {
// this opens a socket and send a login request to the server.
int result = CommunicationManager.login(String email, String password);
switch (result) {
case CommunicationManager.SUCCESS:
// login ok, go on with next screen
break;
case CommunicationManager.WRONG_EMAIL:
status.setTextColor(Color.RED);
status.setText("Wrong Email!");
break;
case CommunicationManager.WRONG_PASSWORD:
status.setTextColor(Color.RED);
status.setText("Wrong Password!");
break;
}
} catch (CommunicationException e) {
status.setTextColor(Color.RED);
status.setText("Unable to estabilish a connection!");
} catch (ProtocolException e) {
status.setTextColor(Color.RED);
status.setText("Protocol error!");
}
これが私が達成したいことです:
- ユーザーが [送信] ボタンをクリックします。
- status textview に「サーバーに接続しようとしています...」と表示されます。
- UI は通信が終了するまで「待機」します。
- status textview はそれに応じて結果を表示します。
しかし、代わりに、ユーザーが [送信] ボタンをクリックすると、通信が完了するまでUI がフリーズします(奇妙なことに、ステータス テキストが表示される前に) (不明なホストに接続しようとしました)。簡単な解決策はソケットのタイムアウトを設定することですが、この種の解決策は好きではありません: UI がまだフリーズしており、どのタイムアウトを設定する必要がありますか?
私の最初の考えは明らかに Thread でしたが、ご覧のとおり、値を返す必要があります。スレッド環境では、スレッドが独立して非同期で実行されるため、これはあまり意味がありません。
したがって、私が必要としているのは、サービスが実行されるのを UI が待機することですが、フリーズすることはありません。ちなみに、戻り値を待つということは、UIがタスクが終了するのを待たなければならないことを意味しているように思えます。
AsyncTask に遭遇しましたが、2 つの大きな欠点があります。
- UI との結びつきが強すぎるように思えます。
- 整数、文字列、およびブール値のパラメーターを使用してサービスを実行したい場合はどうすればよいですか? 延長する必要があり
AsyncTask<Object, Void, Void>
ますか?
どちらも非拡張性につながります。
目標を達成するために何ができますか? サービスへの別のリクエストは、まだ準備ができていない何かに対するリクエストになることに注意してください。そのため、数回 (たとえば 10 分) ごとにリクエストを自動的に繰り返す必要があります。したがって、おそらく で使用できるものが必要になるでしょうがTimerTask
、そのサービスを実行するたびに UI に値を返す必要があります (ステータス テキストを更新して、何が起こっているかをユーザーに知らせることができます)。