¿Cómo evitar la adición de método de inyección para cada vista?

Actualmente, para obtener instancia de, por ejemplo, Picasso en una actividad, tengo que añadir el método de inyección a AppComponent. Cómo evitar la adición del método de inyección, porque tengo un montón de fragmentos y puntos de vista donde se debe inyectar:

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

Fragmento1.clase

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

Mis clases :

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

ACTUALIZAR

Quiero también inyectar adaptadores para fragmentos, y si voy a añadir inyectar a BaseFragment a continuación, BaseFragment tendrá todos los adaptadores para todos los fragmentos de niños

Una solución sería utilizar la herencia para la inyección.

Simplemente defina un BaseFragment con una instancia de @Inject Picasso, cree un método de inyección en su DaggerComponent para este BaseFragment y llámelo en el método onCreate del BaseFragment. Los Fragmentos más específicos como Fragment1, 2 .. pueden heredar de este BaseFragment y usar la instancia de Picasso.

La solución es que puedes hacer la herencia ex: use extend Actividad o Fragmento e inyección en onCreate () en esa clase

A continuación se muestra el ejemplo de lo que hago:

Graph.java

 @Singleton @Component(modules = { AppModule.class, }) public interface Graph { void inject(BaseActivity activity); void inject(BaseFragment fragment); } 

BaseActivity.java

 public class BaseActivity extends AppCompatActivity { protected List<Subscription> mSubscriptions; @Inject protected SharedDB dm; @Inject protected RestApi restApi; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getGraph().inject(this); } public Graph getGraph() { return MyApplication.graph(this); } //... } 

BaseFragment.java

 public class BaseFragment extends Fragment { protected List<Subscription> mSubscriptions; protected Unbinder unbinder; @Inject protected SharedDB dm; @Inject protected RestApi restApi; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); getGraph().inject(this); } public Graph getGraph() { return MyApplication.graph(getActivity()); } //.... } 

MyApplication.java

 public class MyApplication extends Application { private Graph mGraph; @Override public void onCreate() { super.onCreate(); setGraph(DaggerGraph.builder() .appModule(new AppModule(this)) .build()); } public Graph getGraph() { return mGraph; } public void setGraph(Graph graph) { mGraph = graph; } public static Graph graph(Context context) { DominoApp app = (DominoApp) context.getApplicationContext(); return app.getGraph(); } //.... } 

¿Qué pasa con esto?

 public final class MySimpleDelegate { @Inject protected Picasso picasso; @Inject protected Lazy<AdapterOne> lazyAdapterOne; @Inject protected Provider<AdapterTwo> providerAdapterTwo; public MySimpleDelegate(Context context) { MyApplication.getComponent(context).inject(this); } @NonNull public void getPicasso() { return picasso; } @NonNull AdapterOne getAdapterOne() { // the object is injected when the following method is called return lazyAdapterOne.get(); } @NonNull AdapterTwo getAdapterTwo() { // a new instance is created every time this methos is called return providerAdapterTwo.get(); } } public class Fragment1 extends Fragment { private MySimpleDelegate delegate; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); delegate = new MySimpleDelegate(getContext()); Picasso picasso = delegate.getPicasso(); AdapterOne one = delegate.getAdapterOne(); AdapterTwo two = delegate.getAdapterTwo(); } } 

Por cierto, si el único problema es Picasso, también proporciona un método 'setSingletonInstance'. Ver este enlace

EDITAR

Creo que puedes llegar a lo que quieres usando el proveedor de dagas o las fábricas perezosas. Vea el ejemplo anterior.

Lo resolví agregando clase de delegado con la biblioteca lombok

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

Y en una actividad

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

No se puede evitar la adición de método de inyección para cada clase de destino de forma plana, pero se puede evitar llamar a ese método de inyección en cada clase mediante la reflexión. Con esta solución puede llamar a método de inyección sólo en la clase padre y luego ComponentReflectionInjector proporcionaría dependencias para cada clase secundaria en cadena de herencia.

Cómo sería:

 Component { void inject(Child b); } //Activity, fragment - no matter class Parent { ComponentReflectionInjector componentReflectionInjector; void onCreate() { componentReflectionInjector = new ComponentReflectionInjector(Component.class, /* component instance*/); componentReflectionInjector.inject(this); } } //your fragment with Picasso class Child extends Parent { @Inject MyDependency dependency; } 

Y entonces las dependencias estarían disponibles en el método onCreate de Child clase Child .

Esa solución muy discutible valdría por conveniencia perder algún rendimiento y valdría la pena algunos posibles problemas con ProGuard después de la ofuscación, y dagger2 han sido diseñados para no usar la reflexión en todos los marcos DI, pero aún así.

  • Org.codehaus.jackson.JsonParseException: carácter inesperado ('' (código 65279 / 0xfeff)): se espera un valor válido
  • Sipdroid - Otra llamada entrante no se muestra mientras se continúa
  • Error de Android: no se puede realizar esta operación porque se ha cerrado el grupo de conexiones
  • Cómo utilizar Tostadas cuando no puedo usar "esto" como contexto
  • ¿Cómo mostrar la vista previa de 2 cámaras una al lado de la otra?
  • Cómo implementar la comunicación Actividad-Servicio
  • Error de Geocoder grpc
  • Error: Error de ejecución para la tarea ': app: packageRelease'. > No se puede calcular hash de /../AndroidStudioProjects/../classes.jar
  • La división de una cadena funciona en Java, no funciona en Android
  • Gestionar devoluciones de llamada en el cliente android de Socket.io v1.4
  • Transferencia de datos enormes del servlet a la aplicación Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.