Question

I am just beginning with dagger and came across some issues with singleton objects.

So the Singleton looks like this:-

@Module(
    injects = {MainActivity.class,SecondActivity.class}
)
public class MySingle {
   //just to count the number of instances of the class
   public static int thecount=0;
  //the constructor
   public MySingle(){
      Log.v("testing","created");
      thecount++;
    }

@Singleton
@Provides
public MySingle getSingle(){
        return new MySingle();
}
}

The Application class where the object graph is created :-

public class MyApplication extends Application {
private ObjectGraph objectGraph;
@Override
public void onCreate(){
    super.onCreate();
    objectGraph=ObjectGraph.create(new MySingle());

}
public ObjectGraph getObjectGraph(){
    return objectGraph;
}

}

The MainActivity.class:-

public class MainActivity extends ActionBarActivity {
@Inject MySingle mysingle;

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

 //   MyApplication app=(MyApplication)getApplication();
  // app.getObjectGraph().inject(this);
    Log.v("testing", mysingle.thecount + " mainact");
}
 }

So whenever I run this, the number of instances of the singleton "MySingle" is 1 , which is fine. However when i uncomment these lines:-

MyApplication app=(MyApplication)getApplication();
app.getObjectGraph().inject(this);

I get the number of instances as 2. I understand from herethat Dagger creates a singleton for every object graph , but from what I understand by using the above 2 lines, I am injecting MainActivity.class into the existing object graph, obviously the use of which is not apparent to me as of now.. i am just experimenting with it.

Était-ce utile?

La solution

but from what I understand by using the above 2 lines, I am injecting MainActivity.class into the existing object graph

No. You are injecting dependencies into MainActivity. Your module is the dagger module and dependency at once :) First MySingle you create in Application onCreate method, second time you create MySingle during injection.

The @Module annotation should be on class that provides dependencies, and you should provide your dependencies there. Example:

@Module(
    injects = {MainActivity.class,SecondActivity.class}
)
public class DependencyModule {

    @Singleton
    @Provides
    public Repository getSingle(){
        return new InMemoryRepository();
    }
}

Some interface:

public interface Repository {
    List<String> getAllStrings();
}

Its implementation:

public class InMemoryRepository implements Repository {
    @Override
    List<String> getAllStrings() {
        // you can create this list as static list in constructor if you are not sure that it is really singleton :)
        List<String> list = new ArrayList<String>();
        list.add("Hello");
        list.add("World");
        return list;
    }
}

And your Activity:

public class MainActivity extends ActionBarActivity {
    @Inject Repository myRepository;

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

        MyApplication app=(MyApplication)getApplication();
        app.getObjectGraph().inject(this);
        Log.v("testing", repository.getAllString().get(0));
    }
}

You can have few implementations of repository: with database, in memory, in file, and you can only create its implementation and bind it to Repository interface via Module without touching the Activity code! With dagger you can inject into any class, not only Activity

Autres conseils

MySingle should not be the @Module itself. You are creating the module yourself with new MySingle(), and then getting a MySingle instance from the ObjectGraph, which likes your @Provides method says, is also calling new MyModule.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top