使用AndroidAnnotations时@Background和屏幕旋转,如何确保收到回调?

时间:2012-04-14 06:30:25

标签: android annotations android-annotations

使用@Background注释时,我们开始一个新线程。如果我们 当这个线程正在执行旋转屏幕的位置时,我们会 然后失去该线程的回调或如何处理?同 装载机这是在屏幕后面排序,所以我们没有 担心我们使用时经常发生的问题 异步任务。

但@Background注释如何解决这个问题?

1 个答案:

答案 0 :(得分:5)

首先,当你使用@Background注释时,代码在一个单独的线程上执行,但这并不一定意味着将启动一个新线程,因为我们使用一个共同的线程池(可以是替换所有@Background方法。

与AsyncTask一样,@ Background不会处理您的活动的任何生命周期更改。因此,如果您调用@Background方法然后旋转屏幕,那么无论如何,都会在调用它的实例上执行@Background代码。如果将@Background置于属于该活动的方法上,并依次调用@UiThread方法,则可能会在错误的活动实例上调用@UiThread方法,如果发生配置更改。

在Android中,在Loaders之前,处理它的常用方法是使用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有一个非常简单的行为,我不想改变它。但是,我们可以引入具有高级“线程+生命周期”行为的新注释。

Thanx与“Pierre-Yves Ricau”通过googlegroup for androidannotations提供此答案。希望这可以帮助那些可能遇到类似问题的人。