2017-09-21 3 views
0

Ich versuche Dagger 2 zu verwenden, um meine Anwendungsklasse, MyApplication zu injizieren, wie ich es an verschiedenen Orten verwende. Das ist mein Setup Dagger 2.11Dolch 2 - Providing Application Klasse

MyApplication.java

public class MyApplication extends Application implements HasActivityInjector { 

    @Inject 
    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector; 

    @Override 
    public void onCreate() { 
    super.onCreate(); 
    AppInjector.init(this); 
    } 

    @Override 
    public DispatchingAndroidInjector<Activity> activityInjector() { 
    return dispatchingAndroidInjector; 
    } 
} 

AppInjector.java

public class AppInjector { 

    public static void init(MyApplication application){ 

    //Initialize dagger and inject the application 
    DaggerAppComponent.builder().application(application).build().inject(application); 

    application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() { 
     @Override 
     public void onActivityCreated(Activity activity, Bundle aBundle) { 
     handleActivity(activity); 
     } 

     @Override 
     public void onActivityStarted(Activity activity) { 

     } 

     @Override 
     public void onActivityResumed(Activity activity) { 

     } 

     @Override 
     public void onActivityPaused(Activity activity) { 

     } 

     @Override 
     public void onActivityStopped(Activity activity) { 

     } 

     @Override 
     public void onActivitySaveInstanceState(Activity activity, Bundle aBundle) { 

     } 

     @Override 
     public void onActivityDestroyed(Activity activity) { 

     } 
    }); 
    } 

    private static void handleActivity(Activity activity){ 
    if(activity instanceof HasSupportFragmentInjector){ 
     AndroidInjection.inject(activity); 
    } 
    if (activity instanceof FragmentActivity){ 
     ((FragmentActivity) activity).getSupportFragmentManager() 
       .registerFragmentLifecycleCallbacks(
         new FragmentManager.FragmentLifecycleCallbacks() { 
         @Override 
         public void onFragmentCreated(FragmentManager fm, Fragment f, 
                 Bundle savedInstanceState) { 
          if (f instanceof Injectable) { 
          Log.i("LifecycleCallbacks", "injected:" + f); 

          AndroidSupportInjection.inject(f); 
          } 
         } 
         }, true); 
    } 
    } 

AppComponent.java

@Singleton 
@Component(modules = { 
     AndroidInjectionModule.class, 
     ActivityBuilder.class, 
     AppModule.class 
}) 

public interface AppComponent { 
    @Component.Builder 
    interface Builder { 
    @BindsInstance Builder application(Application application); 
    AppComponent build(); 
    } 

    void inject(MyApplication application); 
} 
mit

jedoch versuchen, jedes Mal wenn ich @Inject MyApplication application in einem Konstruktor verwenden, Dolch wirft ein Fehler, dass es keine Möglichkeit hat, es ohne mehr

Furthure @Provides zu schaffen, ich bin nicht sicher, ich soll die Anwendung unter Verwendung von überall und eher nur seine Context? Wenn ja, wie würde ich die Context zur Verfügung stellen?

+0

Versuchen Sie zu beobachten https://github.com/iammert/dagger-android-injection/tree/master – eurosecom

Antwort

2

Werfen Sie einen Blick auf Ihre Builder ...

@Component.Builder 
interface Builder { 
--> @BindsInstance Builder application(Application application); 
    AppComponent build(); 
} 

All Dagger kennt Ihr Application, du bist nie MyApplication erwähnen, es wird scheitern daher injiziert wird.


Ich weiß nicht, warum Sie MyApplication speziell zu injizieren haben würde, aber die einfachste Lösung wäre, es zu ändern Ihre MyApplication stattdessen zu binden ...

@Component.Builder 
interface Builder { 
    @BindsInstance Builder application(/** --> */ MyApplication application); 
    AppComponent build(); 
} 

Dann Dagger kennt MyApplication, aber nicht von Application. Um dies zu beheben, können Sie einfach ein Modul hinzufügen, das die anderen Typen bindet, was einfach genug ist, weil Sie den Untertyp haben ... z.B.

@Module interface AppModule { // could also be an abstract class 
    @Binds Application bindApplication(MyApplication application); 

    // if you also want to bind context 
    @Binds Context bindContext(MyApplication application); 
} 

Und einfach dieses Modul zu Ihrer Komponente hinzufügen.

+0

@Tander, ich denke, das sollte als eine richtige Antwort markiert werden. – azizbekian