2016-08-04 31 views
6

Angenommen, dass here gesagt wurde, liegt es in der Verantwortung des Entwicklers, die Komponenteninstanz beizubehalten, um ihre eigene Bereichslogik zu implementieren (da eine Bereichsmethode dieselbe Instanz für eine bestimmte Komponente zurückgibt).Handhabung der Dolchkomponente bei einer Orientierungsänderung

Wie kann diese Komponentenreferenz während des Aktivitätslebenszyklus sauber gehalten werden?

Beispiel: Sie implementieren das MVP-Muster, sodass Sie einen Moderator in Ihrer Aktivität benötigen. Dieser Presenter kann eine Netzwerkoperation ausführen, um Elemente herunterzuladen. Wenn sich das Gerät dreht, wird Ihre Aktivität zerstört und neu erstellt, aber Sie möchten den Netzwerkbetrieb aufrechterhalten und nur den Prä-Rotations-Presenter zurückbekommen. Stellen Sie sicher, dass die Komponente, die den Presenter mit einem angepassten PerActivity-Bereich bereitstellt, die Lösung ist. Daher müssen Sie die Component-Instanz durch diese Rotation halten, damit dieselbe Presenter-Instanz wie beim ersten Start der Aktivität injiziert wird.

Wie können wir damit umgehen? Ich dachte an eine Art Komponenten-Cache (wie eine HashMap?), Der von einer Anwendungskomponente innerhalb der Application-Klasse bereitgestellt werden könnte.

+2

Ihre Optionen sind: - Komponente Cache in der Anwendung; - benutzerdefinierte Nicht-Konfigurationsinstanz; - Zurückgebliebenes Fragment. – EpicPandaForce

+0

** Persönlich ** Ich blockiere nur Ereignis-Dispatch durch den Ereignis-Bus, während die aktuelle Aktivität nicht "resume" ist, und den Presenter-Status in einem Bündel, dann seinen Zustand wiederherzustellen, bevor die Ereignisse fortgesetzt werden. Und meine Moderatoren sind deshalb nicht gescannt. – EpicPandaForce

+0

Wie können Sie den Presenter-Status in einem Bundle speichern, wenn dieser Status beispielsweise ein OkHttp-Client ist, der Daten herunterlädt? In diesem Fall scheint ein Moderatorcache erforderlich zu sein. –

Antwort

0

Sie können die Implementierung von ribot/android-boilerplate Schaufenster App sehen. Die Lösung, die sie gewählt haben, ist eine static Map<Long, ConfigPersistentComponent> innerhalb der BaseActivity, von der alle Aktivitäten erstrecken.

public class BaseActivity extends AppCompatActivity { 

    private static final AtomicLong NEXT_ID = new AtomicLong(0); 
    private static final Map<Long, ConfigPersistentComponent> sComponentsMap = new HashMap<>(); 

    private ActivityComponent mActivityComponent; 
    private long mActivityId; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     // Create the ActivityComponent and reuses cached ConfigPersistentComponent if this is 
     // being called after a configuration change. 
     mActivityId = savedInstanceState != null ? 
       savedInstanceState.getLong(KEY_ACTIVITY_ID) : NEXT_ID.getAndIncrement(); 

     ConfigPersistentComponent configPersistentComponent; 
     if (!sComponentsMap.containsKey(mActivityId)) { 
      // Creating new component 
      configPersistentComponent = DaggerConfigPersistentComponent.builder() 
        .applicationComponent(BoilerplateApplication.get(this).getComponent()) 
        .build(); 
      sComponentsMap.put(mActivityId, configPersistentComponent); 
     } else { 
      // Reusing component 
      configPersistentComponent = sComponentsMap.get(mActivityId); 
     } 
     mActivityComponent = configPersistentComponent.activityComponent(new ActivityModule(this)); 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putLong(KEY_ACTIVITY_ID, mActivityId); 
    } 

    @Override 
    protected void onDestroy() { 
     if (!isChangingConfigurations()) { 
      // Activity is finishing, removing the component 
      sComponentsMap.remove(mActivityId); 
     } 
     super.onDestroy(); 
    } 

    ... 

} 
0

Netzwerk kann mit App-Kontext arbeiten. Diese ist, wie ich Applicationcomponent entwerfen würde mit appscope Jetzt würde ich dies auf Anwendungsebene erstellt haben ApplicationComponent Shouod nehmen Kontext als externe Abhängigkeit

Als nächstes wird activitycomponent auf activitymodule erstreckt, um mit peractivityscope ..depending auf applicationcomponet

In jeder meiner Aktivitäten würde ich activityComponet erstellen, indem ich es applicationcomponet zur Verfügung stellen. Activity.getapplication(). Getapplicationcomponent()

Hier stellen Sie sicher, Ihre applicationmodule Anbieter von Netzwerk-Methode appscope Wenn das der Fall hat, sollte u gleichen Netzwerk erhalten auch auf App Rorate.

Suchen Sie nach GitHubapplication Beispiel wird den Link in der nächsten Bearbeitung veröffentlichen.

Auch wird es er lohnt sich, bei live zu suchen (aus dem Zusammenhang für diese Frage)