Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Dagger-从其他类访问单例对象_Java_Android_Dependency Injection_Dagger 2 - Fatal编程技术网

Java Dagger-从其他类访问单例对象

Java Dagger-从其他类访问单例对象,java,android,dependency-injection,dagger-2,Java,Android,Dependency Injection,Dagger 2,我一直在努力理解并设置Dagger来处理我的Android项目的依赖注入。我的单一(非双关语)目标是创建我可以跨应用程序访问的单一对象。我已成功地在初始活动中设置了对象。我被困在从其他类访问这些对象的过程中。以下是我目前的设置: 初始应用程序活动 public class SplashScreenActivity extends AppCompatActivity { @Inject SessionKeyExchangerService exchangerService; @

我一直在努力理解并设置Dagger来处理我的Android项目的依赖注入。我的单一(非双关语)目标是创建我可以跨应用程序访问的单一对象。我已成功地在初始活动中设置了对象。我被困在从其他类访问这些对象的过程中。以下是我目前的设置:

初始应用程序活动

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();
    } 
组件类

@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {

    SessionKeyExchangerService provideSessionKeyExchangerService();

    AESCipherService provideCipherService();
}
@Module
public class AppModule {

    @Provides @Singleton
    AESCipherService provideCipherService() {
        return new AESCipherService();
    }

    @Provides @Singleton
    SessionKeyExchangerService provideSessionKeyExchangerService(AESCipherService service) {
        return new SessionKeyExchangerService(service);
    }
}
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)));
    }
模块类

@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {

    SessionKeyExchangerService provideSessionKeyExchangerService();

    AESCipherService provideCipherService();
}
@Module
public class AppModule {

    @Provides @Singleton
    AESCipherService provideCipherService() {
        return new AESCipherService();
    }

    @Provides @Singleton
    SessionKeyExchangerService provideSessionKeyExchangerService(AESCipherService service) {
        return new SessionKeyExchangerService(service);
    }
}
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)));
    }
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;
    }
}
会话密钥交换类

@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {

    SessionKeyExchangerService provideSessionKeyExchangerService();

    AESCipherService provideCipherService();
}
@Module
public class AppModule {

    @Provides @Singleton
    AESCipherService provideCipherService() {
        return new AESCipherService();
    }

    @Provides @Singleton
    SessionKeyExchangerService provideSessionKeyExchangerService(AESCipherService service) {
        return new SessionKeyExchangerService(service);
    }
}
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)));
    }
以下是一些示例输出:

会话ID:217186720
单例验证:790090968

很明显,我不是在访问同一个对象。我意识到,当我试图获取对
AppComponent
类的引用时,我在
AESCipherService
中调用
new
操作符的方式导致了问题的至少一部分,但我不知道如何以任何其他方式获取该引用

我该如何解决这个问题?谢谢

 AppComponent component = DaggerAppComponent.builder().appModule(new AppModule()).build();
不,不。那不是单身汉。作用域提供程序仅对每个组件起作用,这意味着您必须在整个应用程序中使用单个组件,才能拥有实际共享同一作用域提供程序的
@Singleton
作用域模块。在这种情况下,您将在每次创建活动时创建一个新组件

您需要这样创建它们:

public enum Injector {
    INSTANCE;

    private AppComponent appComponent;

    static {
        INSTANCE.appComponent = DaggerAppComponent.create();
    }

    public getAppComponent() {
        return appComponent;
    }
}
您还可以将
应用程序子类化
,并在
onCreate()
中创建一个应用程序

然后

另外,您正在使用基于
@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