首页 \ 问答 \ Dagger - 从其他类访问Singleton对象(Dagger - Accessing Singleton object from other class)

Dagger - 从其他类访问Singleton对象(Dagger - Accessing Singleton object from other class)

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

初始App活动

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

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

我该如何解决? 谢谢!


I've been working to understand and set up Dagger to handle dependency injections for my Android project. My single (no pun intended) objective is to create singleton objects that I can access across my application. I have successfully set up the objects in the initial activity. Where I am stuck is in accessing those objects from other classes. Here is my setup thus 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 is some sample output:

Session ID: 217186720
singleton verification: 790090968

Clearly I'm not accessing the same object. I realize that at least part of the part of the issue stems from the way that I call the new operator in the AESCipherService when I am attempting to get a reference to the AppComponent class, but I don't know how to get this reference any other way.

How do I fix this? Thanks!


原文:https://stackoverflow.com/questions/32211930
更新时间:2023-05-19 19:05

最满意答案

重写类(控制器也是类!)将为新类提供基类所具有的所有未来(除了直接访问私有方法或属性)。 但是不要忘记,基类仍然可以在新类旁边使用。 它依赖于你实例化的类。

$a = new BaseClass();

VS

$a = new NewClass();

那么问题是Symfony会使用哪一个? 这就是你可以通过路由管理的东西。 只要在你的app / config / routing.yml中:

fos_user:
    resource: "@FOSUserBundle/Resources/config/routing/all.xml"

Symfony将使用原始的FOSUserBundle控制器。 只需在vendor / FOS ..目录中找到这些xml文件,然后将它们复制到您自己的项目中。 上面的更改显示规则到您自己的包并更改xml文件中的控制器名称。 当然你也可以编写自己的.yml文件。

阅读更多


Overriding Classes (Controllers are classes too!) will give the new class all the futures that the base-class has (except direct access to private methods or properties). But do not forget that the base-class still can be used beside the new class. It dependence's which class you instantiate.

$a = new BaseClass();

vs

$a = new NewClass();

So the question is which one will Symfony use? And THAT is what you can manage with the routing. as long this is in your app/config/routing.yml:

fos_user:
    resource: "@FOSUserBundle/Resources/config/routing/all.xml"

Symfony will use the original FOSUserBundle controllers. Just find those xml files in the vendor/FOS.. directory and copy them to your own project. Change above showed rule to your own bundle and change the controllernames in the xml files. Of course you could write your own .yml files too.

read more

相关问答

更多

相关文章

更多

最新问答

更多
  • 如何使用自由职业者帐户登录我的php网站?(How can I login into my php website using freelancer account? [closed])
  • 如何打破按钮上的生命周期循环(How to break do-while loop on button)
  • C#使用EF访问MVC上的部分类的自定义属性(C# access custom attributes of a partial class on MVC with EF)
  • 如何获得facebook app的publish_stream权限?(How to get publish_stream permissions for facebook app?)
  • 如何并排放置两个元件?(How to position two elements side by side?)
  • 在MySQL和/或多列中使用多个表用于Rails应用程序(Using multiple tables in MySQL and/or multiple columns for a Rails application)
  • 如何隐藏谷歌地图上的登录按钮?(How to hide the Sign in button from Google maps?)
  • Mysql左连接旋转90°表(Mysql Left join rotate 90° table)
  • 带有ImageMagick和许多图像的GIF动画(GIF animation with ImageMagick and many images)
  • 电脑高中毕业学习去哪里培训
  • 电脑系统专业就业状况如何啊?
  • IEnumerable linq表达式(IEnumerable linq expressions)
  • 如何在Spring测试中连接依赖关系(How to wire dependencies in Spring tests)
  • Solr可以在没有Lucene的情况下运行吗?(Can Solr run without Lucene?)
  • 如何保证Task在当前线程上同步运行?(How to guarantee that a Task runs synchronously on the current thread?)
  • 在保持每列的类的同时向数据框添加行(Adding row to data frame while maintaining the class of each column)
  • 的?(The ? marks in emacs/haskell and ghc mode)
  • 一个线程可以调用SuspendThread传递自己的线程ID吗?(Can a thread call SuspendThread passing its own thread ID?)
  • 延迟socket.io响应,并“警告 - websocket连接无效”(Delayed socket.io response, and “warn - websocket connection invalid”)
  • 悬停时的图像转换(Image transition on hover)
  • IIS 7.5仅显示homecontroller(IIS 7.5 only shows homecontroller)
  • 没有JavaScript的复选框“关闭”值(Checkbox 'off' value without JavaScript)
  • java分布式框架有哪些
  • Python:填写表单并点击按钮确认[关闭](Python: fill out a form and confirm with a button click [closed])
  • PHP将文件链接到根文件目录(PHP Linking Files to Root File Directory)
  • 我如何删除ListView中的项目?(How I can remove a item in my ListView?)
  • 您是否必须为TFS(云)中的每个BUG创建一个TASK以跟踪时间?(Do you have to create a TASK for every BUG in TFS (Cloud) to track time?)
  • typoscript TMENU ATagParams小写(typoscript TMENU ATagParams lowercase)
  • 武陟会计培训类的学校哪个好点?
  • 从链接中删除文本修饰(Remove text decoration from links)