Reputation: 66814
I'm learning Dagger2 and trying to keep it simple example and isolate other features as possible as i can to understand required parts.
*Edit: When i started learning, i'm still, Dagger seems too confusing for a beginner, i was asking if you can inject same User to same Activity whenever that Activity is created. User and Activity should have 1 to 1 relationship.
This is when first time Activities are created.
My question was you navigate back to Activity2 from Activity3, then if it's possible to inject User(101) again only using Dagger? You get back to Activity1 and you get User(100) not new User or Singleton object from component created inside Application.
I was thinking Dagger keeps object like a Pool does and linking Activity instances with objects hashes or keeping states or inner references about injected objects, I was asking if it's possible.*
How can i inject same instance of an object unique to an Activity, it's created when that Activity is created for the first time, and injected again when i navigate to or start that Activity using @ActivityScope? I use the snippets below to construct this example
public class User {
private String name;
private String email;
public User() {
name = "Unknown";
email = "[email protected]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Scope
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {
}
Module class
@Module
public class UserModule {
@ActivityScope
@Provides
User provideUser() {
return new User();
}
}
Component
@ActivityScope
@Component(modules = {UserModule.class})
public interface UserComponent {
void inject(MainActivity mainActivity);
void inject(SecondActivity secondActivity);
void inject(ThirdActivity thirdActivity);
}
I get component from MyApplication and inside MainActivity to test injected objects using userComponent = DaggerUserComponent.create();
public class MainActivity extends AppCompatActivity {
@Inject
User user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
UserComponent daggerUserComponent = DaggerUserComponent.create();
daggerUserComponent.inject(this);
TextView textView = findViewById(R.id.textView);
textView.setText("Main User: " + user.hashCode());
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
}
});
}
}
This one returns different User
every time device is rotated and it's expected behavior since new UserComponent
is created every time.
public class SecondActivity extends AppCompatActivity {
@Inject
User user;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(SecondActivity.this, ThirdActivity.class);
startActivity(intent);
}
});
((MyApplication) getApplication()).getUserComponent().inject(this);
TextView textView = findViewById(R.id.textView);
textView.setText("Second User: " + user.hashCode());
}
}
Application class
public class MyApplication extends Application {
private UserComponent userComponent;
@Override
public void onCreate() {
super.onCreate();
userComponent = DaggerUserComponent.create();
}
public UserComponent getUserComponent() {
return userComponent;
}
}
SecondActivity and ThirdActivity uses UserComponent from MyApplication.
My question is why don't these classes get User unique for each Activity?
They are injected with same User
, how can i make these classes to have their own User
even after navigation between?
Upvotes: 1
Views: 966
Reputation: 195
In the MyApplication
you create an instance of UserComponent
and you use that to inject the User
in the SecondActivity
class. But in MainActivity
class you are recreating the UserComponent
that is why you have different instances of User
in each activity.
You need to use
((MyApplication) getApplication()).getUserComponent().inject(this);
in MainActivity
as well.
Upvotes: 0
Reputation: 2365
You need different components for each of your activities, then they will provide different users for each activity, and if you will keep component alive until the activity is destroyed - it will provide the same user for same activity even after a configuration change. You can achieve it by using ViewModel and destroy component in method onCleared()
Upvotes: 0
Reputation: 1408
I am quite confused with your question. So I am going to answer both of them.
How can i inject same instance of an object to each activity with @ActivityScope? I use the snippets below to construct this example
To inject the same instance of an object to multiple classes, you have to use the same container and scope the provider method.
My question is why don't these classes get User unique for each Activity? They are injected with same User, how can i make these classes to have their own User even after navigation between?
That is because the provideUser
is scoped with @ActivityScope
. Since you are using the same component from your application, you will be getting the same instance of that object everytime.
To summarize, scoped means same instance for all classes using the same container. Unscoped means always a new object instance every inject.
Upvotes: 0