AndroidDev
AndroidDev

Reputation: 21237

Why doesn't the method of my injected dependency run?

I'm trying to refactor some code that relied upon singleton objects, which I am realizing are problematic in Java. My goal is to create a thread-safe instantiation of my AES cipher class that I can access throughout my app.

Following a couple of tutorials about Guice, I have this very basic scenario:

Service Class

@Singleton
public class AESCipherService { // service class

    @Inject
    AESCipherService() {}

    public void makeKeys() {
        Log.d(Constants.TAG, "aes cipher generating keys");
    }
}

Module Class

This is confusing to me since my service class has no subclasses, but all of the examples that I see are about binding a service super class to one of its subclasses.

public class AppInjectorModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(AESCipherService.class);
    }
}

Application Class

public class MyApplication {

    private AESCipherService cipher;

    @Inject
    public void setCipher(AESCipherService cipher) {
        this.cipher = cipher;
    }

    public void makeKeys() {
        cipher.makeKeys();
    }
}

And finally, the activity onCreate where this is all supposed to launch from:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash_screen);

    Log.d(Constants.TAG, "dependency injection test starting");

    Injector injector = Guice.createInjector(new AppInjectorModule());

    // EDIT: added this line, but it never prints!
    Log.d(Constants.TAG, "injector instantiated");

    // instantiates the singleton object ???
    MyApplication app = injector.getInstance(MyApplication.class);
    app.makeKeys();
}

Unfortunately, the only output that I get is dependency injection test starting. I am not seeing aes cipher generating keys, as I am hoping.

Where am I going wrong with dependency injection?

EDIT: I added a few print statements to see where this is failing. It seems that it never returns from instantiating the injector object. Any idea why this is failing? It clearly explains why my service class isn't running.

Upvotes: 2

Views: 356

Answers (2)

durron597
durron597

Reputation: 32343

You are not using Guice idiomatically. The right way to use Guice is to create the injector once at startup, use it to create your initial classes (in this case Activities), and let the injection framework create all your injections down the chain.

Creating the injector is an expensive, slow operation, so you do not want to call it when, say, you click a button; it should happen at application start so users do not notice it.

Since you are developing for Android, consider using Roboguice in order to use Guice properly. See: Using Guice to inject dependencies into an Android activity's constructor

In the meantime, try calling Guice.createInjector in your activity's constructor, saving it as an instance field, then calling getInstance in the onCreate method.

Upvotes: 1

r0101
r0101

Reputation: 405

You need bind also MyApplication.class

public class AppInjectorModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(AESCipherService.class).in(Singleton.class);
        bind(MyApplication.class).in(Singleton.class);
    }
}

Upvotes: 0

Related Questions