0

アプリにスプラッシュ ページがあり、バックグラウンド タスクを開始してダウンロードを開始し、ユーザーが必要なときに準備できるようにしたいと考えています。

たとえば、今週の写真などです。

スプラッシュ スクリーンの開始 (バックグラウンド タスクの開始)
スプラッシュ スクリーンの終了 (バックグラウンド タスクはまだ動作中)
ホーム スクリーンの開始 (一時的な「読み込み中」プレースホルダー)
ユーザーが別のアクティビティに移動する
ダウンロードが終了
する ユーザーがホーム画面に戻り、その週の画像が更新される

非同期タスクのことは知っていますが、非同期タスクがキャンセルされるfinish()と聞いたことがあります。また、キャンセルされないと聞いたことがあります。

この種のタスク、バックグラウンド ロードはサービスで処理するのが最適ですか? バックグラウンドでこのようなものをロードするためのチュートリアルを誰かに教えてもらえますか?

編集:
人々は、UI 作業は UI に、非 UI は非 UI にすべきだと言っています。ハンドラーを検討しましたが、現在のアクティビティがアクティブでないときにリスナーは機能しますか?

メインでハンドラーを開始してからページを切り替えるとしましょう。別のページを表示しているときにリスナーがトリガーされなかったため、戻ってきたときにメイン UI が更新されていないことは確かです。

変数などを格納するためだけにクラスを作成する必要があると思います。サービスが終了すると、「pic_of_week_loaded」が true に設定され、メインのリロード時にこの変数がチェックされます。これについてどうすればいいですか?

4

6 に答える 6

2

クラスから拡張しApplication、その中にスレッド (または AsyncTask) を作成して、基本的にインターネットからコンテンツをダウンロードすることができます。終了後、ホーム画面のアクティビティに通知して、コンテンツをプレースホルダーに表示できます。

于 2012-08-30T17:24:50.947 に答える
1

IntentServiceを使用してバックグラウンド ジョブを実行することを検討してください。そうすれば、アクティビティのライフ サイクルに縛られることはありません。

編集:コメントに従って。

独自のアプリケーション オブジェクトを使用するのは非常に簡単です。次のように作成するだけです。

final public class MyApplication extends Application {
 ....
}

次に、マニフェストを次のように更新します。

<application
    android:name=".MyApplication"
    ...

理論的にはそれだけです。そこに独自のメソッドを追加できるようになりました。非同期タスク操作。また、アプリケーション オブジェクトへのハンドルを取得するには、次のMyApplication app = (MyApplication)getApplicationContext();ようにしapp.XXX()ます。ただし、いくつかの重要な注意事項があります。ApplicationObject で AsyncTask を使用する場合は、Android Bug #20915に注意してください。回避策は、説明に従って、次の場所でこれを行うことですonCreate()

public void onCreate() {
  // Workaround for android bug #20915
  // http://code.google.com/p/android/issues/detail?id=20915
  try {
    Class.forName("android.os.AsyncTask");
  } catch (Exception e) {
    e.printStackTrace();
  }

  super.onCreate();
  ...
于 2012-08-30T17:24:20.770 に答える
1

もう 1 つの選択肢は、Android Asynchronous Http Clientを使用することです。

アクティビティでそれを行うだけですが、表示するときにアクティビティがまだアクティブであることを確認してください(onDestroyがまだ呼び出されていないことを確認してください)。

次に、結果をキャッシュして、Web から再度読み込む必要がないようにします (ファイル名に日付を保存すると、画像の日付がわかるので、キャッシュに最新のものがあるかどうかがわかります)。

于 2012-08-30T17:44:13.343 に答える
1

(1)Applicationサブクラスでグローバル状態を保持することと (2) を使用AsyncTaskすることが、この場合の両方の悪いアプローチである理由を説明しようとします。

(1) アプリがフォアグラウンドになく、現在アプリで実行中のサービスがない場合、OS はアプリ プロセスを強制終了する可能性があります。詳細については、次の記事を参照してください: Android でグローバル変数を宣言する方法は?

(2)AsyncTaskは見た目よりもトリッキーです。:) たとえば、((OS < 1.6) || (OS >= 3.0)) の場合、すべてのタスクはデフォルトで同じバックグラウンド ワーカー スレッドで実行されます。つまり、現在の Java プロセスのすべてのタスクは、唯一のバックグラウンド スレッドで実行されます。したがって、他のアクティビティで次に開始される可能性のあるタスクは、最初の/初期化タスクが完了するまで待機する必要があります。これはあなたが望んでいるものではないと思います(ユーザーが Home アクティビティから他のアクティビティに移動し、別のアクティビティが を使用してデータをロードする必要がある場合はAsyncTask、最初の / init タスクが迅速に行われるようにしてください。後続のタスクをブロックします)。もちろん、first/init タスクの作業量が大きくない場合は、この点について心配する必要はありません。AsyncTaskこの投稿でどのように機能するかについての詳細:複数の AsyncTask を同時に実行する -- 不可能ですか?

したがって、IntentService起動時に必要なイメージ/日付をダウンロードするために使用することをお勧めします。データをダウンロードすると、フラグが設定SharedPreferencesされ、ブロードキャストが送信されます。この時点で、ホーム アクティビティは次の 3 つの状態になっている可能性があります。

  • アクティブ (渡されましonResume()たが、まだではありませんonPause())
  • 一時停止中 ( を通過しましonPause()たが、まだ に戻っていませんonResume)
  • 破壊されました

アクティブな間、ブロードキャスト レシーバーを使用してサービスをリッスンします。一時停止すると、ブロードキャスト レシーバーの登録を解除しますが、アクティブになると、最初に からフラグをチェックしSharedPreferencesます。フラグがまだ設定されていない場合は、ブロードキャスト レシーバーを登録します。

于 2012-08-30T19:15:49.630 に答える
0

1. AndroidAsyncTaskに導入されたのは、それが何を知っているかを示すためですPainless Threadingが、ここではそうではないと思います....

2.今では、UI スレッドで UI 作業を維持し、Non-UI スレッドで非 UI 作業を維持することは常に良いことであり、それは Androidのバージョンの登場からルールになりました。HoneyComb

3.バックグラウンドでいくつかのものをダウンロードしたいので、UI に出力を反映することは含まれません。CountDownLatch次に、java.util.concurrent の Classを調べると思います。

4.それ以外の場合は、いつでもバックグラウンドで実行できますNon-UI thread

于 2012-08-30T17:25:20.483 に答える
0

バックグラウンド タスクにはThreadsandを使用することを好みます。Handlersスレッドはバックグラウンドで何らかの操作を実行し、タスクが完了するとハンドラーを更新して UI を更新します。以下にサンプルコードを示します。

Handler handler = new Handler() { //Declare this as a global variable to the class
      @Override
      public void handleMessage(Message msg) {
    //display each item in a single line
          if(msg.obj.equals("update subcat")){
              subcategoryAdapter.notifyDataSetChanged();
          }else if (msg.obj.equals("update products")){
              productsAdapter.notifyDataSetChanged();
          }else if (msg.obj.equals("update cat")){
              categoryAdapter.notifyDataSetChanged();
          }
     }
 };

バックグラウンド タスクは次のとおりです。

Thread background = new Thread(new Runnable() {

    @Override
    public void run() {
        getSubCategories(((Categories)searchResults.get(pos)).ID);
        handler.sendMessage(handler.obtainMessage(pos, "update subcat"));
        }
    });
    background.start();
于 2012-08-30T17:27:54.613 に答える