2015-03-29 5 views
12

http://konmik.github.io/snorkeling-with-dagger-2.html Nach könnte ichWie können Abhängigkeiten in jede Art von Objekt mit Dagger2 injiziert werden?

inject(Anything anything) 

in AppComponent.java fügen Sie einfach, aber das ist für mich nicht funktioniert, in dem Artikel Beispiel:

@Singleton 
@Component(modules = AppModule.class) 
public interface AppComponent { 
    void inject(MainActivity activity); 
    void inject(MainFragment fragment); 
    void inject(MainToolbarView view); 
} 

Wenn ich versuche, meine Abhängigkeiten zu injizieren in fragment die injizierten Mitglieder bleiben null. Welchen offensichtlichen Fehler fehle ich hier?

relevanten Quellen:

ApplicationComponent.java

@Singleton 
@Component(
    modules = ApplicationModule.class 
) 
public interface ApplicationComponent { 
    void injectApplication(BaseApplication application); 

    Prefs providePrefs(); 
} 

ApplicationModule.java

@Module 
public class ApplicationModule { 
    private final Application application; 

    public ApplicationModule(Application application) { 
     this.application = application; 
    } 

    @Provides 
    Application application() { 
     return application; 
    } 

    @Singleton 
    @Provides 
    Prefs providePrefs() { 
     return Prefs.with(application); 
    } 
} 

ActivityComponent.java

@AScope 
@Component(
    dependencies = { 
     ApplicationComponent.class 
    }, 
    modules = ActivityModule.class 
) 
public interface ActivityComponent extends ApplicationComponent { 
    void injectActivity(BaseActivity activity); 
    void injectFragment(BaseFragment fragment); 
} 

ActivityModule.java

@Module 
public class ActivityModule { 
    private final Activity activity; 

    public ActivityModule(Activity activity) { 
     this.activity = activity; 
    } 

    @Provides 
    Activity activity() { 
     return activity; 
    } 

    @Provides 
    Context context() { 
     return activity; 
    } 
} 

BaseApplication.java

public class BaseApplication extends Application { 
    private ApplicationComponent component; 


    @Override 
    public void onCreate() { 
     super.onCreate(); 
     component = createComponent(); 

     component.injectApplication(this); 
    } 

    private ApplicationComponent createComponent() { 
     return Dagger_ApplicationComponent.builder() 
      .applicationModule(new ApplicationModule(this)) 
      .build(); 
    } 

    public ApplicationComponent getComponent() { 
     return component; 
    } 
} 

BaseActivity.java

public class BaseActivity extends ActionBarActivity implements HasComponent<ActivityComponent> { 
    ActivityComponent component; 

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

     component = Dagger_ActivityComponent.builder() 
      .applicationComponent(((BaseApplication) getApplication()).getComponent()) 
      .activityModule(new ActivityModule(this)) 
      .build(); 

     component.injectActivity(this); 

    } 

    @Override 
    public ActivityComponent getComponent() { 
     return component; 
    } 
} 

BaseFragment.java

public class BaseFragment extends Fragment { 

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

     ((BaseActivity)getActivity()).getComponent().injectFragment(this); 
    } 
} 

ListFragment.java

public class ListFragment extends BaseFragment { 

    @Inject ListFragmentPresenterImpl listFragmentPresenter; 

    public static ListFragment newInstance(){ 
     ListFragment result = new ListFragment(); 

     return result; 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     super.onCreateView(inflater, container, savedInstanceState); 

     View rootView = inflater.inflate(R.layout.list_fragment, container, false); 

     Log.d("",listFragmentPresenter.sayHello()); // NPE HERE 

     return rootView; 
    } 
} 

ListFragmentPresenterImpl.java

public class ListFragmentPresenterImpl implements ListFragmentPresenter { 

    @Inject 
    public ListFragmentPresenterImpl() { 
    } 

    @Override 
    public String sayHello() { 
     return "hello"; 
    } 
} 

In Dagger_ActivityComponent der generierte Code sieht wie folgt aus:

@Override 
public void injectActivity(BaseActivity activity) { 
    baseActivityMembersInjector.injectMembers(activity); 
} 

@Override 
public void injectFragment(BaseFragment fragment) { 
    MembersInjectors.noOp().injectMembers(fragment); 
} 

sollte hier kein baseFragmentMemebersInjector sein?

Danke!

Antwort

11

Inject Kind Fragmente statt BaseFragment. In Ihrem Fall:

public class ListFragment extends BaseFragment { 

    @Inject ListFragmentPresenterImpl listFragmentPresenter; 

    public static ListFragment newInstance(){ 
     ListFragment result = new ListFragment(); 
     return result; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     ((MainActivity)getActivity()).getComponent().injectFragment(this); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     super.onCreateView(inflater, container, savedInstanceState); 
     View rootView = inflater.inflate(R.layout.list_fragment, container, false); 
     Log.d("",listFragmentPresenter.sayHello()); // NPE HERE 
     return rootView; 
    } 
} 

Und in Ihrer Komponentenklasse:

@AScope 
@Component(dependencies = ApplicationComponent.class, 
      modules = ActivityModule.class) 
interface ActivityComponent { 
    void injectActivity(MainActivity activity); 
    void injectFragment(ListFragment fragment); 
    // Put any more injects here, if BaseFragment has 
    // any other children that need to be injected, for example: 
    void inject(MapFragment fragment); 
    void inject(DetailFragment fragment); 
} 

Eltern -> Child Injektion funktioniert nicht in Dagger 2. Es wurde here bedeckt, here und this SO question.

+0

danke! es funktioniert jetzt – chrystolin

+0

Kirill hast du mich gerade nach 2 zermürbenden Stunden gerettet. Diese SO war schwierig für mich zu finden, da ich den Oberflächenfehler einer NPE betrachtete. Ich denke, ich habe die falsche Frage gestellt. Ich werde versuchen, den Code-Teil Ihrer Antwort zu bearbeiten, da ich verwirrt war, weil ich dachte, ich sollte mehr Komponenten-Interfaces für jedes Fragment erstellen. – lemuel

+1

@lemuel Ich bin froh, dass es hilft. Sie können gerne Änderungen vornehmen, aber es ist möglicherweise nicht gut, eine einzelne Komponente zu erstellen, um Dinge überall zu injizieren. In großen Projekten besser, sie in Komponenten und Unterkomponenten zu trennen. –

Verwandte Themen