Java – dagger – accessing singleton objects from other classes

I have been trying to understand and set up dagger to handle dependency injection of Android projects. My single (no pun) goal is to create singleton objects that I can access in my application. I have successfully set up objects in the initial activity. Where am I trapped accessing these objects from other classes. This is my setting so far:

Initial app 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();
    } 

Component class

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

    SessionKeyExchangerService provideSessionKeyExchangerService();

    AESCipherService provideCipherService();
}

Module 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;
    }
}

Sessionkeyexchanger 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)));
    }

Here are some sample outputs:

Obviously, I did not visit the same object. I realized that at least part of the problem was derived from the way I called new operators in AESCipherService when I tried to get references to AppComponent classes, but I didn't know how to get this reference in another way.

How can I solve it? thank you!

resolvent:

 AppComponent component = DaggerAppComponent.builder().appModule(new AppModule()).build();

Nonono. This will not be a single person. The scope provider only applies to each component, which means that you must use a single component throughout the application so that modules within the @ singleton scope actually share the same scope provider. In this case, a new component will be created each time you create an activity

You need to create them like this:

public enum Injector {
    INSTANCE;

    private AppComponent appComponent;

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

    public getAppComponent() {
        return appComponent;
    }
}

You can also subclass application and create one in oncreate()

also

@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!
}

then

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();

In addition, you are creating with an @ module based instance, so @ inject is missing from the constructor

@Inject
public SessionKeyExchangerService(AESCipherService cipherService) {
    this.cipherService = cipherService;
}

also

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

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>