2015-03-29 9 views
12

Według http://konmik.github.io/snorkeling-with-dagger-2.html może po prostu dodaćJak wstrzyknąć zależności do dowolnego obiektu za pomocą Dagger2?

inject(Anything anything) 

do AppComponent.java, ale to nie działa dla mnie, na przykład artykuły:

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

Gdyby spróbować wstrzyknąć współzależności do mojego fragment wstrzykniętych członków pozostaje pusty. Jakiego oczywistego błędu tu brakuje?

Istotne źródła:

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

W Dagger_ActivityComponent wygenerowany kod wygląda następująco:

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

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

nie powinno tu być baseFragmentMemebersInjector?

Dzięki!

Odpowiedz

11

Wstrzyknij fragmenty podrzędne zamiast BaseFragment. W twoim przypadku:

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

A w swojej klasie komponentów:

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

dominującej -> wtrysk Dziecko nie działa w Dagger 2. Została ona pokryta here, here i this SO question.

+0

Dziękuję! działa teraz – chrystolin

+0

Kirill właśnie uratowałeś mnie po 2 wyczerpujących godzinach. To było dla mnie trudne do znalezienia, ponieważ patrzyłem na błąd powierzchni, który był NPE. Sądzę, że to ja zadaję niewłaściwe pytanie. Spróbuję edytować część kodu z twoją odpowiedzią, bo pomyliłem się myśląc, że powinienem stworzyć więcej interfejsów Komponentów dla każdego Fragmentu. – lemuel

+1

@lemuel Cieszę się, że to pomaga. Zapraszamy do edycji, ale może nie być dobrze, aby stworzyć pojedynczy komponent, który wszędzie wstrzykuje rzeczy. W dużych projektach lepiej rozdzielić je na komponenty i podkomponenty. –

Powiązane problemy