1

サーバーと頻繁にやり取りする必要があるアプリを開発しています。

そのため、ユーザーは名前とパスワードを入力し、承認後に次のタスクを実行する必要があります。

  1. アプリは、このユーザーのすべての受信メッセージと送信メッセージをフェッチし、それらを SQLite データベースにロードする必要があります。
  2. すべてのユーザー フレンド (ID、名前、contact_data を含む JSON) を取得し、それをアプリのデータベースにロードします
  3. 次のアクティビティにジャンプし、ローカル データベースからの収入メッセージを表示します。

    この操作の問題は遅すぎて、アプリが新しいアクティビティを開始したときにデータベースから取得するものは何もありません:AsyncTasks はまだ完了していません。すべての完了を待つために AsyncTask.get() を使用する必要がありますが、これには待つこと16秒以上!

    スレッドを使用するか、フェッチしたデータをデータベースにロードする前にメモリに保持し、データベースからフェッチする代わりに新しいアクティビティに表示しますか?しかし、データベース タスクがなくても、他のフェッチ タスクは待機するのに 10 秒近くかかります!それで、私は何をすべきですか?

4

3 に答える 3

2

ここでかなりうまくいかないことがいくつかあります。

  1. ネットワークに AsyncTasks を使用しないでください。サービスをご利用ください。つまり、これは、開始したアクティビティが停止するとすぐに AsyncTask が停止するためです。これは、ネットワーク リクエストが簡単に中止され、データが失われ、アクティビティが再び開かれたときに再度開始する必要があることを意味します。

  2. AsyncTasks で .get() を使用しないでください。これにより、UI スレッドはタスクが完了するまで待機し、AsyncTask のアイデア全体が役に立たなくなります。つまり、これは UI をブロックします。

あなたがすべきこと:

  1. サービスの使用について読んでください。これに役立つ RoboSpice と呼ばれる優れたオープンソース ライブラリを参照することもできます。

  2. AsyncTasks で .get() を使用するのをやめます。いつ完了したかを知りたい場合は、リスナーを使用してください。

  3. 可能であれば、スレッドプールで AsyncTasks を実行します ( myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); )。

于 2013-04-02T12:23:05.040 に答える
0

AsyncTasks は、複数の小さなタスクを同時に実行するためのものではありません。ドキュメントの引用

最初に導入されたとき、AsyncTasks は単一のバックグラウンド スレッドでシリアルに実行されました。DONUT 以降、これはスレッドのプールに変更され、複数のタスクが並行して動作できるようになりました。HONEYCOMB 以降、並列実行によって発生する一般的なアプリケーション エラーを回避するために、タスクは単一のスレッドで実行されます。

複数のタスクを同時に実行する場合Threadは、a で s を使用します。ThreadPool

この状況をどのように処理するかは、あなた次第です。バックグラウンド タスクに時間がかかりすぎる場合は、いつでもアラート ダイアログをユーザーに表示し、データが入力されたらアクティビティに移動できます。これが発生すると、多くのアプリで「読み込み中」画面が表示されます。Spinnerデータがまだ利用できない場合は、「読み込み中」コントロールを表示することもできます。空白の画面を表示しないでください。

サーバー側の呼び出しが制御下にある場合は、何らかのキャッシュを使用して時間を短縮します。1 秒以上続く API 呼び出しは、せっかちなユーザーにつながります。そうでない場合は、前の段落で説明した手法のいずれかを使用してください。@Perception のテクニックも、できるかどうかを検討する 1 つです。

于 2013-04-02T12:13:20.620 に答える