0

I am new to Dagger and DI in general. I am trying to inject a PendingIntent and an AlarmManager object using this following module.

@Module(
        injects = { 
                LocationMonitorService.class,
        },
        library = true,
        addsTo = ApplicationModule.class,
        complete = false
        )
public class LocationMonitorServiceModule {

    private Context mContext;
    private Intent mIntent;

    LocationMonitorServiceModule(Context context, Intent intent) {
        mContext = context;
        mIntent = intent;
        System.out.println("location monitor service module");

    }

    @Provides PendingIntent provideGcmKeepAlivePendingIntent() {
        return PendingIntent.getBroadcast(mContext, 0, mIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    }

    @Provides  AlarmManager provideGcmKeepAliveAlarmManager() {
        return (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
    }



}

Here is the class I am trying to inject into.

public class LocationMonitorService extends Service {

    @Inject DeviceLocationClient deviceLocationClient;
    Intent gcmKeepAliveIntent;
    @Inject AlarmManager alarmManager;
    @Inject PendingIntent gcmKeepAlivePendingIntent;
    @Inject GetMarkerRequestTimer markerRequestTimer;
    @Inject PushRequestTimer pushRequestTimer;
    @Inject Bus mBus;

    @Override
    public void onCreate() {
        super.onCreate();
        System.out.println("creating the LocationMonitorService");
        gcmKeepAliveIntent = new Intent("com.gmail.npnster.first_project.gcmKeepAlive");
        injectMe();
        mBus.register(this);
        alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, 4*60*1000, gcmKeepAlivePendingIntent);


    }

    void injectMe() {
        ObjectGraph objectGraph = Injector.getInstance().getObjectGraph();
        System.out.println(String.format("currentGraph = %s", objectGraph));
        ObjectGraph extendedGraph = objectGraph.plus(new LocationMonitorServiceModule(this,gcmKeepAliveIntent));
        System.out.println(String.format("extendedGraph = %s", extendedGraph));
        extendedGraph.inject(this);

    }

Update

Adding my module used to create the base graph

@Module(
    injects = { 
                MapMarker.class,
                ApiRequestRepository.class,
                DeviceLocationClient.class,
                GcmBroadcastReceiver.class,
                HomeActivity.PlaceholderFragment.class,
                MapActivity.WrapperFragment.class,
                MainActivity.class,
                RegisterGcmActivity.class,
                SignUpActivity.class,
                ApiExActivity.class,
                LocationMonitorService.class,
                MapMarker.class,
                MapMarkers.class,
                MapPresenter.class,
                UsersListActivity.class,
                PersistData.class,
                LocationMonitorService.GetMarkerRequestTimer.class,
                LocationMonitorService.PushRequestTimer.class,
                ApiCheckerActivity.PlaceholderFragment.class,  //can probably remove this class completely
                MyApp.class
              },
    library = true,
    complete = false
    )

public class ApplicationModule {

    private MyApp mApp;

    public ApplicationModule(MyApp app) {
        System.out.println("creating production version of ApplicationModule");
        mApp = app;
    }

    @Provides @Singleton
    public MyApp provideMyApp() {
        return mApp;
    }

    @Provides
    public GoogleMapMarkerParameters provideGoogleMapMarkerParameters() {
        System.out.println("inside dagger -non mock");
        return new GoogleMapMarkerParameters();
    }


    @Provides @Singleton
    public Bus provideBus () {
        return new Bus();
    }

    @Provides @Singleton
    public PersistData providePersistData () {
        System.out.println(String.format("mApp = %s", mApp));
        return new PersistData(mApp);
    }

    @Provides 
    public LocationMonitorService.GetMarkerRequestTimer provideGetMarkerRequestTimer () {
        return new LocationMonitorService.GetMarkerRequestTimer(10*60000,10000);
    }   

    @Provides 
    public LocationMonitorService.PushRequestTimer providePushRequestTimer () {
        return new LocationMonitorService.PushRequestTimer(10*60000,60000);
    }              
}

The problem is I never get past the objectGraph.plus() step.

here is a snip of the logcat output.

Note the currentGraph = .... but the lack of extendedGraph = ....

the "no injectable members" errors makes sense given that it does no look like the module was added to the graph

08-23 13:16:51.825 I/System.out( 3319): creating the LocationMonitorService
08-23 13:16:51.825 I/System.out( 3319): currentGraph = dagger.ObjectGraph$DaggerObjectGraph@b0fb4d08
08-23 13:16:51.825 I/System.out( 3319): location monitor service module
08-23 13:16:51.835 D/AndroidRuntime( 3319): Shutting down VM
08-23 13:16:51.835 W/dalvikvm( 3319): threadid=1: thread exiting with uncaught exception (group=0xb0ccfb20)
08-23 13:16:51.835 I/Process ( 3319): Sending signal. PID: 3319 SIG: 9
08-23 13:16:51.835 W/InputDispatcher( 1260): channel 'b12b5970 com.gmail.npnster.first_project/com.gmail.npnster.first_project.MainActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x9
08-23 13:16:51.835 E/InputDispatcher( 1260): channel 'b12b5970 com.gmail.npnster.first_project/com.gmail.npnster.first_project.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
08-23 13:16:51.835 E/AndroidRuntime( 3319): FATAL EXCEPTION: main
08-23 13:16:51.835 E/AndroidRuntime( 3319): Process: com.gmail.npnster.first_project, PID: 3319
08-23 13:16:51.835 E/AndroidRuntime( 3319): java.lang.RuntimeException: Unable to create service com.gmail.npnster.first_project.LocationMonitorService: java.lang.IllegalStateException: Errors creating object graph:
08-23 13:16:51.835 E/AndroidRuntime( 3319):   android.app.AlarmManager has no injectable members. Do you want to add an injectable constructor? required by class com.gmail.npnster.first_project.LocationMonitorService
08-23 13:16:51.835 E/AndroidRuntime( 3319):   android.app.PendingIntent has no injectable members. Do you want to add an injectable constructor? required by class com.gmail.npnster.first_project.LocationMonitorService
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at android.app.ActivityThread.handleCreateService(ActivityThread.java:2582)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at android.app.ActivityThread.access$1800(ActivityThread.java:135)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at android.os.Handler.dispatchMessage(Handler.java:102)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at android.os.Looper.loop(Looper.java:136)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at android.app.ActivityThread.main(ActivityThread.java:5017)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at java.lang.reflect.Method.invokeNative(Native Method)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at java.lang.reflect.Method.invoke(Method.java:515)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at dalvik.system.NativeStart.main(Native Method)
08-23 13:16:51.835 E/AndroidRuntime( 3319): Caused by: java.lang.IllegalStateException: Errors creating object graph:
08-23 13:16:51.835 E/AndroidRuntime( 3319):   android.app.AlarmManager has no injectable members. Do you want to add an injectable constructor? required by class com.gmail.npnster.first_project.LocationMonitorService
08-23 13:16:51.835 E/AndroidRuntime( 3319):   android.app.PendingIntent has no injectable members. Do you want to add an injectable constructor? required by class com.gmail.npnster.first_project.LocationMonitorService
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at dagger.internal.ThrowingErrorHandler.handleErrors(ThrowingErrorHandler.java:34)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at dagger.internal.Linker.linkRequested(Linker.java:182)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at dagger.internal.Linker.linkAll(Linker.java:109)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at dagger.ObjectGraph$DaggerObjectGraph.linkEverything(ObjectGraph.java:244)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at dagger.ObjectGraph$DaggerObjectGraph.plus(ObjectGraph.java:203)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at com.gmail.npnster.first_project.LocationMonitorService.injectMe(LocationMonitorService.java:50)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at com.gmail.npnster.first_project.LocationMonitorService.onCreate(LocationMonitorService.java:35)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     at android.app.ActivityThread.handleCreateService(ActivityThread.java:2572)
08-23 13:16:51.835 E/AndroidRuntime( 3319):     ... 10 more
08-23 13:16:51.835 W/ActivityManager( 1260):   Force finishing activity com.gmail.npnster.first_project/.HomeActivity
08-23 13:16:51.835 I/ActivityManager( 1260): Process com.gmail.npnster.first_project (pid 3319) has died.
08-23 13:16:51.835 W/ActivityManager( 1260): Force removing ActivityRecord{b11d7a80 u0 com.gmail.npnster.first_project/.MainActivity t28}: app died, no saved state
08-23 13:16:51.855 W/InputDispatcher( 1260): Attempted to unregister already unregistered input channel 'b12b5970 com.gmail.npnster.first_project/com.gmail.npnster.first_project.MainActivity (server)'
08-23 13:16:51.855 I/WindowState( 1260): WIN DEATH: Window{b12b5970 u0 com.gmail.npnster.first_project/com.gmail.npnster.first_project.MainActivity}
nPn
  • 16,254
  • 9
  • 35
  • 58
  • Have you tried adding a \@Inject annotated constructor? "If your class has \@Inject-annotated fields but no \@Inject-annotated constructor, Dagger will use a no-argument constructor if it exists. Classes that lack @Inject annotations cannot be constructed by Dagger." – hoomi Aug 23 '14 at 17:55
  • thanks, but that's mainly for cases were you _dont_ have a @Provides annoated method, In this case I am trying to provide an instance of a third party class, namely a pendingIntend and alarmManager. – nPn Aug 23 '14 at 19:39

1 Answers1

0

I did manage to get this to work by removing the LocationMonitorrService.class from the injects = { ... } list in the base module.

My LocationMonitorServiceModule when added to base module can inject the LocationMonitorService class, but since I added more @Injects to the LocationMonitorService class (which are provided by the new module) , the base module no longer can inject that class.

While I have this working, and it does seem to make some sense, it still seems like a bit of black magic.

nPn
  • 16,254
  • 9
  • 35
  • 58