Nick Unuchek Nick Unuchek - 1 month ago 16
Android Question

How to avoid adding of inject method for each view?

Currently to get instance of for example Picasso in an activity, I need to add inject method to AppComponent. How to avoid adding of the inject method, because I have a lot of fragments and views where it should be injected:

AppComponent.class:

@ForApplication
@Singleton
@Component(
modules = {AppModule.class,OkHttpClientModule.class,NetworkApiModule.class,NetworkAuthModule.class})
public interface AppComponent {
void inject(Fragment1 obj);
void inject(Fragment2 obj);
void inject(Fragment3 obj);
void inject(Fragment4 obj);
void inject(Fragment5 obj);
void inject(Fragment6 obj);
...
}


Fragment1.class

public class Fragment1 extends Fragment {
@Inject Picasso mPicasso;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyApplication.getComponent(getContext()).inject(this);
}
}


My classes :

AppModule.class:

@Module
public class AppModule {
private MyApplication mApplication;

public AppModule(@NonNull MyApplication mApplication) {
this.mApplication = mApplication;
}

@Provides
@NonNull
@Singleton
public Application provideApplication() {
return mApplication;
}


@Provides
@ForApplication
Context provideContext(){
return mApplication;
}

@Provides
@Singleton
Picasso providesPicasso(@ForApplication Context context) {
return new Picasso.Builder(context).build();
}
}


ForApplication.class:

@Scope
@Retention(RUNTIME)
public @interface ForApplication {
}


MyApplication.class

public class MyApplicationextends Application {
static Context mContext;
private AppComponent component;
@Override
public void onCreate() {
super.onCreate();
mContext = this;

setupComponent();
}

private void setupComponent() {
component = DaggerAppComponent.builder().appModule(new AppModule(this)).build();
component.inject(this);
}

public AppComponent getComponent() {
if (component==null)
setupComponent();
return component;
}



public static AppComponent getComponent(Context context) {
return ((MyApplication) context.getApplicationContext()).getComponent();
}


UPDATE

I want also inject adapters for fragments, and if I'll add inject to BaseFragment then BaseFragment will have all adapters for all child fragments

Answer

I resolved it by adding Delegate class with lombok library

@Accessors(prefix = "m")
public class AdapterDelegate {
    @Getter @Inject Lazy<FlatAdapter> mFlatAdapterLazy;
    public AdapterDelegate(){
       MyApplication.getComponent(MyApplication.getContext()).inject(this);
    }

    public static AdapterDelegate get() {
        return new AdapterDelegate();
    }
}

And in an Activity

public class MainActivity extends Activity {
    FlatAdapter mFlatAdapter = AdapterDelegate.get().getFlatAdapterLazy().get();