2017-11-13 11 views
0

@ContributesAndroidInjectorアノテーション(https://google.github.io/dagger/android.html)を使用して作業ダガー設定を行っています。Dagger 2.11:@ContributesAndroidInjectorを使用している場合のローカルシングルトン

 Component Application 
    /     \ 
Subcomponent DrawerActivity Subcomponent SubActivity 
     | 
Subcomponent DrawerFragment 

SubActivityとDrawerActivityでは、@ Singletonとマークされた同じリポジトリインスタンスを使用しています。

@Singleton 
@Component(modules = { 
     AndroidInjectionModule.class, 
     AppModule.class, 
     ActivityBuilderModule.class 
}) 
public interface AppComponent { 
    @Component.Builder 
    interface Builder{ 
     @BindsInstance Builder application(Application application); 

     AppComponent build(); 
    } 
    void inject(App app); 
} 

@Module 
public abstract class ActivityBuilderModule { 
    @PerActivity 
    @ContributesAndroidInjector(modules = {DrawerActivityModule.class, 
    FragmentBuilderModule.class}) 
    abstract DrawerActivity bindDrawerActivity(); 

    @PerActivity 
    @ContributesAndroidInjector(modules = {DrawerActivityModule.class}) 
    abstract SubActivity bindSubActivity(); 
} 

@Module 
public abstract class FragmentBuilderModule { 
    @PerFragment 
    @ContributesAndroidInjector(modules = DrawerFragmentModule.class) 
    abstract DrawerFragment provideDrawerFragment(); 
} 


@Singleton 
public class Repository{ 
    private SomeClass mSomeClass; 

    @Inject 
    public VehicleRepositoryImpl(SomeClass someClass) { 
     mSomeClass = someClass; 
    } 
} 


public class App extends Application implements HasActivityInjector{ 
    @Inject 
    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     if (BuildConfig.DEBUG) { 
      Timber.plant(new Timber.DebugTree()); 
     } 
     AppComponent component = DaggerAppComponent.builder().application(this) 
       .build(); 
     component.inject(this); 
    } 

    @Override 
    public AndroidInjector<Activity> activityInjector() { 
     return dispatchingAndroidInjector; 
    } 
}  

public class DrawerActivity extends AppCompatActivity implements HasSupportFragmentInjector{ 
    @Inject 
    DispatchingAndroidInjector<Fragment> fragmentDispatchingAndroidInjector; 

    @Override 
    public AndroidInjector<Fragment> supportFragmentInjector() { 
     return fragmentDispatchingAndroidInjector; 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     AndroidInjection.inject(this); 
     super.onCreate(savedInstanceState); 
    } 
} 

public class DrawerFragment extends Fragment { 
    @Inject 
    ViewModelFactory mViewModelFactory; //repository gets injected into factory 

    @Override 
    public void onCreate(@Nullable Bundle savedInstanceState) { 
     AndroidSupportInjection.inject(this); 
     super.onCreate(savedInstanceState); 
    } 
} 

public class SubActivity extends AppCompatActivity{ 
    @Inject 
    Repository mRepository; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     AndroidInjection.inject(this); 
     super.onCreate(savedInstanceState); 
    } 
} 

私は今ユーザー管理を追加する必要があります。これにはLoginActivityが必要です。私はLoginActivityでリポジトリを利用できるようにしたくありません。だから私はどのように私はまだ新しい@ContributesAndroidInjectorアノテーションを使用してこれを達成することができますDrawerActivity/Subactivity/DrawerFragement

   Component Application 
     /      \ 
    @UserScope      @LoginScope 
    Subcomponent DrawerActivity  SubComponent LoginActivity 
     |      \ 
Subcomponent DrawerFragment Subcomponent SubActivity 

のローカルシングルトンスコープ「UserScope」を作成したいのですが?

私はそれがこのブログ投稿で同じように動作します:http://frogermcs.github.io/building-userscope-with-dagger2/

答えて

-2

私はこのレポでのようにそれをすることによって私の問題を解決しました:

https://github.com/ragdroid/Dahaka

その貢献に感謝を!

更新1:コード例が追加されました。

このグラフは、コード例の概要を示しています。

    Component Application 
     /        \ 
    @UserScope       @LoginScope 
    Subcomponent UserComponent   SubComponent LoginActivity 
     |      \ 
Subcomponent DrawerActivity Subcomponent SubActivity 
     | 
SubComponent DrawerFragment 

コード例(代は私がコメントでお知らせください欠落している場合):

1.ダガーセットアップ

AppComponentはダガーグラフのルートです:

@Singleton 
@Component(modules = { 
     AndroidSupportInjectionModule.class, 
     AppModule.class, 
     AppBindingModule.class 
}) 
public interface AppComponent extends AndroidInjector<DaggerApplication> { 
    @Component.Builder 
    interface Builder{ 
     @BindsInstance Builder application(Application application); 

     AppComponent build(); 
    } 

    void inject(MyApp app); 

    UserComponent.Builder userBuilder(); 

    UserManager getUserManager(); 
} 

サブコンポーネントをバインドするモジュール:

@Module(subcomponents = UserComponent.class) 
public abstract class AppBindingModule { 

    @ContributesAndroidInjector(modules = LoginModule.class) 
    @LoginScope 
    abstract LoginActivity loginActivity(); 

}  

UserComponentは、ユーザがログインしている場合にのみ使用されるクラスのインスタンスを保持している。UserModule.classに設けられたすべてのクラスは「LocalSingletons」活動およびフラグメントコンポーネントのようなさらなるサブコンポーネントでとして入手可能です。

@UserScope 
@Subcomponent(modules = { 
     UserBindingModule.class, 
     UserModule.class, 
     AndroidSupportInjectionModule.class 
}) 
public interface UserComponent extends AndroidInjector<DaggerApplication> { 
    void inject(UserManager userManager); 

    @Subcomponent.Builder 
    interface Builder{ 
     UserComponent build(); 
    } 
} 

UserBindingModuleは、どのアクティビティサブコンポーネントがUserComponentに属しているかを定義します。

@Module 
public abstract class UserBindingModule { 
    @ContributesAndroidInjector(modules = {DrawerBindingModule.class, AndroidSupportInjectionModule.class}) 
    abstract DrawerActivity bindDrawerActivity(); 

    @ContributesAndroidInjector 
    abstract SubActivity bindSubActivity(); 
} 

DrawerBindingModuleは、どのフラグメントサブコンポーネントがDrawerActivityComponentに属しているかを定義します。

@Module 
public abstract class DrawerBindingModule { 
    @DrawerFragmentScope 
    @ContributesAndroidInjector(modules = DrawerFragmentModule.class) 
    abstract DrawerFragment provideDrawerFragment(); 
} 

UserManagerは、ユーザーログイン/ログアウトとそれ以降のすべてのアクティビティ注入を処理します。

@Singleton 
public class UserManager implements HasActivityInjector { 
    private final UserComponent.Builder userComponentBuilder; 
    @Inject 
    DispatchingAndroidInjector<Activity> activityInjector; 

    private UserComponent userComponent; 

    @Inject 
    public UserManager(UserComponent.Builder builder) { 
     this.userComponentBuilder = builder; 
    } 

    public void logIn(){ 
     createUserSession(); 
    } 

    private void createUserSession() { 
     userComponent = userComponentBuilder.build(); 
     userComponent.inject(this); 
    } 

    public boolean isLoggedIn() { 
     return userComponent != null; 
    } 

    public void logOut() { 
     userComponent = null; 
    } 

    @Override 
    public AndroidInjector<Activity> activityInjector() { 
     return activityInjector; 
    } 
} 

2.アプリの+のアクティビティ+フラグメントクラス

public class MyApp extends Application implements HasActivityInjector{ 
    @Inject 
    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector; 

    @Inject 
    UserManager mUserManager; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     if (BuildConfig.DEBUG) { 
      Timber.plant(new Timber.DebugTree()); 
     } 
     AppComponent component = DaggerAppComponent.builder().application(this) 
       .build(); 
     component.inject(this); 
    } 

    @Override 
    public AndroidInjector<Activity> activityInjector() { 
     return mUserManager.activityInjector(); 
    } 
} 


public class LoginActivity extends AppCompatActivity { 
    Intent mOpenDrawerActivity; 
    private ActivityLoginBinding binding; 

    @Inject 
    UserManager mUserManager; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     AndroidInjection.inject(this); 
     super.onCreate(savedInstanceState); 
     ... 
    } 

    void openDrawerActivity(){ 
     mUserManager.logIn(); 
     mOpenDrawerActivity = new Intent(this, DrawerActivity.class); 
     startActivity(mOpenDrawerActivity); 
     finish(); 
    } 
} 


public class DrawerActivity extends BaseUserActivity implements HasSupportFragmentInjector{ 
    @Override 
    protected void onCreate(Bundle savedInstanceState) {   
     super.onCreate(savedInstanceState); 
     ... 
    }   

    private void onLogout(){ 
     logoutUser(); 
    } 
} 


public abstract class BaseUserActivity extends BaseActivity { 
    @Inject 
    UserManager userManager; 

    @Override 
    protected void onCreate(@Nullable Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     if (!userManager.isLoggedIn()) { 
      finishView(); 
     } 
    } 

    @Override 
    protected void androidInject() { 
     AndroidInjection.inject(this); 
    } 

    protected void logoutUser() { 
     userManager.logOut(); 
     finishView(); 
    }  
} 


public abstract class BaseActivity extends AppCompatActivity implements HasSupportFragmentInjector { 
    @Inject 
    DispatchingAndroidInjector<Fragment> injector; 

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

    protected void androidInject() { 
     AndroidInjection.inject(this); 
    } 

    public void finishView() { 
     startActivity(new Intent(this, LoginActivity.class)); 
     finish(); 
    } 

    @Override 
    public AndroidInjector<Fragment> supportFragmentInjector() { 
     return injector; 
    } 
} 
+0

ソリューションが何であるかを答え自体に記載してください。そうでなければ、リポジトリが削除されたときにその答えは役に立たなくなる。 – BDL

+0

不十分な回答をおかけして申し訳ありません。私は今いくつかのコードを追加しました。何かが足りないとコメントしてください。 – piveloper

関連する問題