2015-03-29 20 views
12

Secondo http://konmik.github.io/snorkeling-with-dagger-2.html ho potuto solo aggiungereCome iniettare dipendenze in qualsiasi tipo di oggetto con Dagger2?

inject(Anything anything) 

in AppComponent.java, ma questo non funziona per me, nell'esempio articoli:

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

Se provo per iniettare le dipendenze nel mio frammentare i membri iniettati rimangono nulli. Che errore evidente mi manca qui?

fonti pertinenti:

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"; 
    } 
} 

Nel Dagger_ActivityComponent il codice generato assomiglia a questo:

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

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

non dovrebbe qui essere un baseFragmentMemebersInjector?

Grazie!

risposta

11

Iniettare frammenti figlio anziché BaseFragment. Nel tuo caso:

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

E nella classe Component:

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

Parent -> iniezione bambino non funziona in Dagger 2. Era coperto here, here e this SO question.

+0

grazie! Funziona ora – chrystolin

+0

Kirill mi hai appena salvato dopo 2 estenuanti ore. Questa SO era difficile da trovare per me, poiché stavo osservando l'errore di superficie che era un NPE. Immagino che sia stato io a fare la domanda sbagliata. Proverò a modificare la parte del codice della risposta, poiché mi sono confuso pensando di dover creare più interfacce Component per ogni frammento. – lemuel

+1

@lemuel sono contento che aiuti. Sei il benvenuto per le modifiche, tuttavia, potrebbe non essere buono creare un singolo componente per iniettare cose ovunque. Nei grandi progetti è meglio separarli in componenti e sottocomponenti. –

Problemi correlati