2012-04-14 4 views
4

Bei Verwendung der @Background-Annotation starten wir einen neuen Thread. Und wenn wir während dieser Thread ausgeführt wird, wo der Bildschirm zu drehen, werden wir dann den Rückruf von diesem Thread verlieren oder wie wird das gehandhabt? Mit der Loader ist dies hinter dem Bildschirm aussortiert, so dass wir nicht kümmern uns um die Probleme, die häufig zurück aufgetreten, wenn wir asynchrone Aufgaben verwendet haben.@Background und Bildschirm Rotation bei Verwendung von AndroidAnnotations, um sicherzustellen, dass die Rückrufe erhalten werden?

Aber wie geht die @Background Annotation damit um?

Antwort

5

Zuerst, wenn Sie die @Background-Annotation verwenden, wird der Code in einem separaten Thread ausgeführt, aber dies bedeutet nicht unbedingt, dass ein neuer Thread gestartet wird, da wir einen gemeinsamen Thread-Pool verwenden ersetzt werden) für alle @ Background-Methoden.

Wie eine AsyncTask verarbeitet @Background keine Änderungen am Lebenszyklus Ihrer Aktivitäten. Wenn Sie also eine @Background-Methode aufrufen und der Bildschirm dann gedreht wird, wird der @Background-Code unabhängig von der Art der Instanz ausgeführt, auf der er aufgerufen wurde. Wenn @Background auf einer Methode platziert wird, die zu der Aktivität gehört, und abwechselnd eine @UiThread-Methode aufruft, besteht das Risiko, dass die @UiThread-Methode für die falsche Aktivitätsinstanz aufgerufen wird, wenn eine Konfigurationsänderung stattgefunden hat. In Android, vor Loadern, war die übliche Methode, AsyncTask zu verwenden, Verweise auf diese Aufgaben in onRetainNonConfigurationInstance() zu behalten und nach einer Konfigurationsänderung an die neue Aktivität zu binden.

In der neuesten Version bietet AndroidAnnotations die Instance Annotation @NonConfiguration, die mit @EBean/@Bean und @Background kombiniert werden kann, um denselben Effekt zu erzielen.

Hier ist ein Beispielcode (nicht getestet, von gmail geschrieben):

@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); 
    } 
} 

Ich denke, dass wir Lösungen noch besser zur Verfügung stellen könnte, aber es gibt viele verschiedene Anwendungsfälle, und wir müssen darüber nachdenken, das Einkaufszentrum. Im Moment hat @Background ein sehr einfaches Verhalten und ich möchte das nicht ändern. Wir könnten jedoch neue Annotationen mit einem fortgeschrittenen "thread + lifecycle" Verhalten einführen.

Danke an "Pierre-Yves Ricau" für die Bereitstellung dieser Antwort über die googlegroup für Androidannotations. Hoffe, das wird anderen helfen, die mit einem ähnlichen Problem stecken bleiben könnten.

Verwandte Themen