Dagger - 从其他类访问Singleton对象

时间:2015-08-25 18:57:37

标签: java android dependency-injection dagger-2

我一直在努力理解并设置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);
    }
}

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类

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

显然,我没有访问同一个对象。我意识到至少部分问题源于我在尝试获取new类的引用时调用AESCipherService中的AppComponent运算符的方式,但我不知道如何以任何其他方式获得此引用。

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

1 个答案:

答案 0 :(得分:3)

500 error

Nononononono。那不会是单身人士。范围提供程序仅适用于每个组件,这意味着您必须在整个应用程序中使用单个组件,以使 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; } } 并在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;
}