Dagger - 从其他 class 访问单例对象
Dagger - Accessing Singleton object from other class
我一直在努力理解和设置 Dagger 来处理我的 Android 项目的依赖注入。我的单例(没有双关语意)objective 是创建我可以在我的应用程序中访问的单例对象。我已经成功地设置了初始 activity 中的对象。我被卡住的地方是从其他 classes 访问这些对象。到目前为止,这是我的设置:
初始应用程序Activity
public class SplashScreenActivity extends AppCompatActivity {
@Inject SessionKeyExchangerService exchangerService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
AppComponent component = DaggerAppComponent.builder().appModule(new AppModule()).build();
// establish the session id as a singleton object
exchangerService = component.provideSessionKeyExchangerService();
// test whether I can access the singleton from another class
exchangerService.sendEncryptedKeyToServer();
}
组件Class
@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {
SessionKeyExchangerService provideSessionKeyExchangerService();
AESCipherService provideCipherService();
}
模块Class
@Module
public class AppModule {
@Provides @Singleton
AESCipherService provideCipherService() {
return new AESCipherService();
}
@Provides @Singleton
SessionKeyExchangerService provideSessionKeyExchangerService(AESCipherService service) {
return new SessionKeyExchangerService(service);
}
}
AESCipherService
public class AESCipherService {
private Long sessionId;
public AESCipherService() {
sessionId = makeSessionId();
Log.d(Constants.TAG, "Session ID: " + Long.toString(sessionId));
}
private Long makeSessionId() {
// this generates a random unsigned integer in the space {0, 2^32-1)
Random random = new Random();
return random.nextLong() & 0xffffffffL;
}
public Long getSessionId() {
return sessionId;
}
}
会话密钥交换器Class
public class SessionKeyExchangerService {
private static SessionKeyExchangerService exchanger;
private AESCipherService cipherService;
@Inject
public SessionKeyExchangerService(AESCipherService cipherService) {
this.cipherService = cipherService;
}
public void sendEncryptedKeyToServer () {
// the next line is almost certainly part of the problem
// but I don't know how to fix!!!
AppComponent component = DaggerAppComponent.builder().appModule(new AppModule()).build();
AESCipherService cipherService = component.provideCipherService();
Long sessionID = cipherService.getSessionId();
Log.d(Constants.TAG, "singleton verification: " + (Long.toString(sessionID)));
}
这是一些示例输出:
Session ID: 217186720
singleton verification: 790090968
很明显,我访问的不是同一个对象。我意识到问题的至少一部分源于我在 AESCipherService
中调用 new
运算符的方式,当我试图获取对 AppComponent
[= 的引用时55=],但我不知道如何以任何其他方式获取此引用。
我该如何解决这个问题?谢谢!
AppComponent component = DaggerAppComponent.builder().appModule(new AppModule()).build();
不不不不不不。那不会是单身人士。 Scoped providers 仅针对每个组件工作,这意味着您必须在整个应用程序中使用单个组件才能拥有 @Singleton
个实际上共享相同范围提供程序的范围模块。在这种情况下,每次创建 activity 时都会创建一个新组件。
您需要像这样创建它们:
public enum Injector {
INSTANCE;
private AppComponent appComponent;
static {
INSTANCE.appComponent = DaggerAppComponent.create();
}
public getAppComponent() {
return appComponent;
}
}
您也可以子类化 Application
并在 onCreate()
中创建一个。
还有
@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {
SessionKeyExchangerService provideSessionKeyExchangerService();
AESCipherService provideCipherService();
void inject(SplashScreenActivity splashScreenActivity); //does NOT support base class injection! Concrete classes only!
}
然后
public class SplashScreenActivity extends AppCompatActivity {
@Inject SessionKeyExchangerService exchangerService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
Injector.INSTANCE.getAppComponent().inject(this);
// establish the session id as a singleton object
// exchangerService = component.provideSessionKeyExchangerService(); //totally not needed
// test whether I can access the singleton from another class
exchangerService.sendEncryptedKeyToServer();
此外,您正在使用基于 @Module
的实例创建,因此在
中的构造函数中丢失 @Inject
@Inject
public SessionKeyExchangerService(AESCipherService cipherService) {
this.cipherService = cipherService;
}
还有
public void sendEncryptedKeyToServer () {
// the next line is almost certainly part of the problem
// but I don't know how to fix!!!
//AppComponent component = DaggerAppComponent.builder().appModule(new AppModule()).build(); //you don't need this here at all
//AESCipherService cipherService = component.provideCipherService(); //already provided in constructor
我一直在努力理解和设置 Dagger 来处理我的 Android 项目的依赖注入。我的单例(没有双关语意)objective 是创建我可以在我的应用程序中访问的单例对象。我已经成功地设置了初始 activity 中的对象。我被卡住的地方是从其他 classes 访问这些对象。到目前为止,这是我的设置:
初始应用程序Activity
public class SplashScreenActivity extends AppCompatActivity {
@Inject SessionKeyExchangerService exchangerService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
AppComponent component = DaggerAppComponent.builder().appModule(new AppModule()).build();
// establish the session id as a singleton object
exchangerService = component.provideSessionKeyExchangerService();
// test whether I can access the singleton from another class
exchangerService.sendEncryptedKeyToServer();
}
组件Class
@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {
SessionKeyExchangerService provideSessionKeyExchangerService();
AESCipherService provideCipherService();
}
模块Class
@Module
public class AppModule {
@Provides @Singleton
AESCipherService provideCipherService() {
return new AESCipherService();
}
@Provides @Singleton
SessionKeyExchangerService provideSessionKeyExchangerService(AESCipherService service) {
return new SessionKeyExchangerService(service);
}
}
AESCipherService
public class AESCipherService {
private Long sessionId;
public AESCipherService() {
sessionId = makeSessionId();
Log.d(Constants.TAG, "Session ID: " + Long.toString(sessionId));
}
private Long makeSessionId() {
// this generates a random unsigned integer in the space {0, 2^32-1)
Random random = new Random();
return random.nextLong() & 0xffffffffL;
}
public Long getSessionId() {
return sessionId;
}
}
会话密钥交换器Class
public class SessionKeyExchangerService {
private static SessionKeyExchangerService exchanger;
private AESCipherService cipherService;
@Inject
public SessionKeyExchangerService(AESCipherService cipherService) {
this.cipherService = cipherService;
}
public void sendEncryptedKeyToServer () {
// the next line is almost certainly part of the problem
// but I don't know how to fix!!!
AppComponent component = DaggerAppComponent.builder().appModule(new AppModule()).build();
AESCipherService cipherService = component.provideCipherService();
Long sessionID = cipherService.getSessionId();
Log.d(Constants.TAG, "singleton verification: " + (Long.toString(sessionID)));
}
这是一些示例输出:
Session ID: 217186720
singleton verification: 790090968
很明显,我访问的不是同一个对象。我意识到问题的至少一部分源于我在 AESCipherService
中调用 new
运算符的方式,当我试图获取对 AppComponent
[= 的引用时55=],但我不知道如何以任何其他方式获取此引用。
我该如何解决这个问题?谢谢!
AppComponent component = DaggerAppComponent.builder().appModule(new AppModule()).build();
不不不不不不。那不会是单身人士。 Scoped providers 仅针对每个组件工作,这意味着您必须在整个应用程序中使用单个组件才能拥有 @Singleton
个实际上共享相同范围提供程序的范围模块。在这种情况下,每次创建 activity 时都会创建一个新组件。
您需要像这样创建它们:
public enum Injector {
INSTANCE;
private AppComponent appComponent;
static {
INSTANCE.appComponent = DaggerAppComponent.create();
}
public getAppComponent() {
return appComponent;
}
}
您也可以子类化 Application
并在 onCreate()
中创建一个。
还有
@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {
SessionKeyExchangerService provideSessionKeyExchangerService();
AESCipherService provideCipherService();
void inject(SplashScreenActivity splashScreenActivity); //does NOT support base class injection! Concrete classes only!
}
然后
public class SplashScreenActivity extends AppCompatActivity {
@Inject SessionKeyExchangerService exchangerService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
Injector.INSTANCE.getAppComponent().inject(this);
// establish the session id as a singleton object
// exchangerService = component.provideSessionKeyExchangerService(); //totally not needed
// test whether I can access the singleton from another class
exchangerService.sendEncryptedKeyToServer();
此外,您正在使用基于 @Module
的实例创建,因此在
@Inject
@Inject
public SessionKeyExchangerService(AESCipherService cipherService) {
this.cipherService = cipherService;
}
还有
public void sendEncryptedKeyToServer () {
// the next line is almost certainly part of the problem
// but I don't know how to fix!!!
//AppComponent component = DaggerAppComponent.builder().appModule(new AppModule()).build(); //you don't need this here at all
//AESCipherService cipherService = component.provideCipherService(); //already provided in constructor