2016-08-04 9 views
6

hereとした場合、スコープロジックを実装するためにコンポーネントインスタンスを保持するのは開発者の責任です(スコープされたメソッドは特定のコンポーネントに対して同じインスタンスを返すため)。方向変更時のダガーコンポーネントの処理

このコンポーネントの参照をアクティビティのライフサイクルを通じて維持するにはどうすればよいですか?

例:MVPパターンを実装しているため、アクティビティ内にプレゼンターが必要です。このプレゼンターはアイテムをダウンロードするためにネットワーク操作を行うことができます。デバイスが回転すると、あなたのアクティビティは破壊され、再作成されますが、ネットワーク操作はそのままにして、プリローテーションプレゼンターを取り戻したいと考えています。

PresenterにカスタムPerActivityスコープを提供するコンポーネントのスコープはソリューションです。したがって、このローテーションを通じてComponentインスタンスを保持して、アクティビティの最初の起動時にPresenterの同じインスタンスを注入する必要があります。

どうすればこの問題に対処できますか?私は、Applicationクラス内にあるApplication Componentによって提供されることができる、ある種のコンポーネントキャッシュ(HashMapのようなもの)を考えました。

+2

オプションは次のとおりです。 - カスタム非構成インスタンス。 - 保持された断片。 – EpicPandaForce

+0

**個人的に**現在の活動が「再開」されていない間にイベントバスを介してイベントディスパッチをブロックし、プレゼンターの状態をバンドルに入れて、イベントが再開される前の状態を復元します。したがって私の発表者はスコープがありません。 – EpicPandaForce

+0

この状態で、たとえば、OkHttpクライアントがデータをダウンロードしている場合に、プレゼンターの状態をバンドルに保存するにはどうすればよいですか?この場合、プレゼンタキャッシュが必要になります。 –

答えて

0

ribot/android-boilerplateショーケースアプリの実装を見ることができます。彼らが選択した解決策はBaseActivityの中にstatic Map<Long, ConfigPersistentComponent>を持つことです。そこからすべてのアクティビティが拡張されます。

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

ネットワークはアプリコンテキストで動作します。 これは私が今、私はこれが ApplicationComponent Shouodを外部依存性としてコンテキストをとる

次はactivitycomponent peractivityscopeがapplicationcomponet

に..dependingでactivitymoduleに拡張されたアプリケーション層の上に作成されなければならないのAppScope で Applicationcomponentを設計する方法をあります私のすべての活動では、私はそれを提供することによってactivityComponetを作成しますapplicationcomponet このapplicationcomponetはからアクセスできます。 Activity.getapplication()。getapplicationcomponent()

ここで、ネットワークメソッドを提供しているアプリケーションモジュールがappscopeを持っていることを確認してください。 これがケースの場合、アプリケーションでも同じネットワークを取得する必要があります。

GitHubapplicationサンプルを探すと、次の編集でリンクを投稿します。

また、livedata(この質問のコンテキスト外)を見る価値があります

関連する問題