我正在学习Dagger2,并尝试保持简单的示例并尽可能地隔离其他功能,以了解所需的部分。
*编辑:当我开始学习时,我仍然感到困惑,对于初学者来说,匕首似乎太令人困惑,我在问您是否可以在创建该活动时向同一活动注入同一用户。用户和活动应具有1到1的关系。
这是第一次创建活动。
我的问题是您从Activity3导航回到Activity2,那么是否有可能仅使用Dagger再次注入User(101)?您回到Activity1,并从Application内部创建的组件中获得User(100)而不是新User或Singleton对象。
我在想Dagger像Pool一样保持对象,并将Activity实例与对象散列联系起来,或者保持有关注入对象的状态或内部引用,我问这是否可能。*
我该如何注入一个Activity特有的对象的同一实例,它是在首次创建该Activity时创建的,当我使用@ActivityScope导航到或启动该Activity时又重新注入的?我使用下面的代码片段构建此示例
public class User {
private String name;
private String email;
public User() {
name = "Unknown";
email = "abc@xyz.com";
}
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
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {
}
模块类
@Module
public class UserModule {
@ActivityScope
@Provides
User provideUser() {
return new User();
}
}
组件
@ActivityScope
@Component(modules = {UserModule.class})
public interface UserComponent {
void inject(MainActivity mainActivity);
void inject(SecondActivity secondActivity);
void inject(ThirdActivity thirdActivity);
}
我从MyApplication和MainActivity内部获取组件,以使用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);
}
});
}
}
每次旋转设备时,此操作都会返回不同的User
,这是自每次创建新的UserComponent
以来的预期行为。
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());
}
}
应用程序类
public class MyApplication extends Application {
private UserComponent userComponent;
@Override
public void onCreate() {
super.onCreate();
userComponent = DaggerUserComponent.create();
}
public UserComponent getUserComponent() {
return userComponent;
}
}
SecondActivity和ThirdActivity使用MyApplication中的UserComponent。
我的问题是,为什么这些类不能使每个Activity的用户唯一?
它们被注入相同的User
,即使在它们之间导航后,如何使这些类具有自己的User
?
答案 0 :(得分:0)
我很困惑你的问题。所以我要回答这两个问题。
我怎样才能将对象的相同实例注入到每个活动中 @ActivityScope?我使用下面的代码片段构建此示例
要将对象的相同实例注入多个类,必须使用相同的容器并确定provider方法的作用域。
我的问题是,为什么这些类不能使每个类的用户唯一 活动?他们注入了相同的用户,我该怎么做 类之间甚至在导航之后也拥有自己的用户?
这是因为provideUser
的范围是@ActivityScope
。由于您正在使用应用程序中的相同组件,因此每次都将获得该对象的相同实例。
总而言之,作用域表示使用同一容器的所有类的相同实例。无作用域意味着每次注入总是一个新的对象实例。
答案 1 :(得分:0)
您需要为每个活动使用不同的组件,然后它们将为每个活动提供不同的用户,如果在活动被销毁之前将组件保持活动状态-即使更改了配置,它也将为同一活动提供相同的用户。您可以通过使用ViewModel并销毁方法onCleared()
答案 2 :(得分:0)
在require 'sinatra/base'
module Tir
class App < Sinatra::Base
# code
end
end
中创建一个configure_options
的实例,并使用该实例将MyApplication
注入UserComponent
类中。但是在User
类中,您正在重新创建SecondActivity
,这就是为什么每个活动中都有不同的MainActivity
实例的原因。
您需要使用UserComponent
在User
中也是如此。