4

@Background アノテーションを使用する場合、新しいスレッドを開始します。このスレッドの実行中に画面を回転させると、そのスレッドからのコールバックが失われるのでしょうか、それともどのように処理されるのでしょうか? ローダーを使用すると、これは画面の後ろで整理されるため、非同期タスクを使用したときに頻繁に発生した問題について心配する必要はありません。

しかし、@Background アノテーションはこれをどのように処理するのでしょうか?

4

1 に答える 1

6

まず、@Background アノテーションを使用すると、コードは別のスレッドで実行されますが、これは必ずしも新しいスレッドが開始されることを意味するわけではありません。すべての @Background メソッド。

AsyncTask と同様に、@Background はアクティビティのライフサイクルの変更を処理しません。そのため、@Background メソッドを呼び出してから画面を回転させると、@Background コードは呼び出されたインスタンスで実行されます。@Background がアクティビティに属するメソッドに配置され、次に @UiThread メソッドを呼び出す場合、構成の変更が発生した場合に @UiThread メソッドが間違ったアクティビティ インスタンスで呼び出されるリスクがあります。

ローダー以前の Android では、これを処理する通常の方法は、AsyncTask を使用し、これらのタスクへの参照を onRetainNonConfigurationInstance() に保持し、構成の変更後にそれらを新しいアクティビティに再バインドすることでした。

最新のリリースでは、AndroidAnnotations は @NonConfiguration インスタンス アノテーションを提供します。これを @EBean / @Bean および @Background と組み合わせて同じ効果を得ることができます。

サンプル コードは次のとおりです (テストされていません。gmail から作成されています)。

@EActivity
public class MyActivity extends Activity {

  // Using @NonConfigurationInstance on a @Bean will automatically update the context ref on configuration changes (if the bean is not a singleton)
  @NonConfigurationInstance
  @Bean
  MyBackgroundTask task;

  @Click
  void myButtonClicked() {
    task.doSomethingInBackground();
  }

  void showResult(MyResult result) {
    // do something with result
  }

}


@EBean
public void MyBackgroundTask {

  @RootContext
  MyActivity activity;

  @Background
  void doSomethingInBackground() {
      // do something
     MyResult result = XXX;

      updateUI(result);
  }

  // Notice that we manipulate the activity ref only from the UI thread
  @UiThread
  void updateUI(MyResult result) {
    activity.showResult(result);
  }
}

もっと良いソリューションを提供できると思いますが、さまざまなユースケースがあり、それらすべてについて考える必要があります。現時点では、@Background の動作は非常に単純であり、それを変更したくありません。ただし、高度な「スレッド + ライフサイクル」動作を備えた新しい注釈を導入することはできます。

androidannotations の googlegroup を介してこの回答を提供してくれた "Pierre-Yves Ricau" に感謝します。これが、同様の問題で立ち往生する可能性のある他の人に役立つことを願っています.

于 2012-04-14T06:32:11.353 に答える