首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android Dagger项目中未注入字段

Android Dagger项目中未注入字段
EN

Stack Overflow用户
提问于 2014-08-18 10:44:19
回答 1查看 3.1K关注 0票数 5

我在Android上玩Dagger。我创建了一个模型UserPreference、一个名为PreferenceModule的模块和另一个类UserPreferenceTest,它是对PreferenceModule的测试。我有以下3个java文件

UserPreference.java

代码语言:javascript
复制
package com.sigicn.preference;

import javax.inject.Inject;

import com.sigicn.commonmodels.Application;

public class UserPreference {
    public String name, weiboAccount;

    @Inject
    public Application[] frequentlyUsedApps;
}

然后是PreferenceModule.java

代码语言:javascript
复制
package com.sigicn.preference;

import javax.inject.Singleton;

import com.sigicn.commonmodels.Application;
import com.sigicn.utils.MiscUtils;

import dagger.Module;
import dagger.Provides;

@Module(library = true, complete = true)
public class PreferenceModule {

    @Provides @Singleton UserPreference provideUserPreference() {
        UserPreference userPreference = new UserPreference();
        userPreference.frequentlyUsedApps = provideApplications();
        return userPreference;
    }

    @Provides @Singleton Application[] provideApplications() {
        return new Application[]{
                new Application(
                        MiscUtils.generateUUID(), "Youtube"),
                new Application(
                        MiscUtils.generateUUID(), "Pixi")
            };
    }

}

然后是UserPreferenceTest.java

代码语言:javascript
复制
package com.sigicn.test.preference;

import javax.inject.Inject;

import com.sigicn.preference.PreferenceModule;
import com.sigicn.preference.UserPreference;

import dagger.Module;
import dagger.ObjectGraph;
import android.test.AndroidTestCase;

public class UserPreferenceTest extends AndroidTestCase {
    @Module(injects = {UserPreference.class, UserPreferenceTest.class}, 
            includes = PreferenceModule.class)
    static class TestModule {
    }

    ObjectGraph objectGraph; 

    @Inject
    UserPreference userPreference;

    @Override
    protected void setUp() throws Exception {
        if (objectGraph == null) {
            objectGraph = ObjectGraph.create(new TestModule());
        }
        super.setUp();
    }

    public void testFrequentlyUsedApps()
    { 
        UserPreference localUserPreference = objectGraph.get(UserPreference.class);
        assertNotNull(localUserPreference);
        assertEquals(localUserPreference.frequentlyUsedApps.length, 2);

        objectGraph.inject(this);
        assertNotNull(userPreference);
        assertEquals(userPreference.frequentlyUsedApps.length, 2);
        assertSame(localUserPreference, userPreference);
        assertSame(localUserPreference.frequentlyUsedApps, userPreference.frequentlyUsedApps);
    }
}

但不知道为什么,frequentlyUsedApps of UserPreference没有像预期的那样被注入。知道为什么吗?

更新:

我想我已经找出原因了。这是因为我手动创建UserPreference并在提供程序中使用它。如果我删除UserPreference的提供程序,让Dagger自动连接它,那么字段frequentlyUsedApps就会被注入。所以这是我的错,没有很好地理解达格。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-18 12:27:20

我认为您需要添加一些ObjectGraph#inject调用。

在每个有@Inject注释的类中,还需要调用您创建的ObjectGraph的inject方法。

我也为这件事挣扎了一段时间。我认为基本模式是:

  1. 注释您的字段以表示要注入它们。
  2. 创建一个模块,为这些@注入“提供”实例
  3. 在某个地方创建图形(似乎大多数人都在应用程序类中这样做)
  4. 在您想要从模块中注入内容的类中,获取图形的一个实例并调用inject(this)。

我开始使用单例而不是应用程序类,因为至少现在我有一些地方想要注入应用程序本身。

所以,这就是我目前正在做的事情,这似乎很管用。

代码语言:javascript
复制
public class Injector {

    private static Injector mInjector;
    private ObjectGraph mObjectGraph;
    private MyApp mApp;

    private Injector() {

    }

    public static Injector getInstance() {
        if (mInjector == null) {
            mInjector = new Injector();
        }
        return mInjector;
    }

    protected List<Object> getModules() {
        return Arrays.asList(
                                new ApplicationModule(mApp),
                                new AndroidModule(mApp)
                             );
    }

    public void inject(Object object) {
        getObjectGraph().inject(object);
    }

    public ObjectGraph getObjectGraph() {
        return mObjectGraph;
    }

    public void initialize(MyApp app) {
        mApp = app;
        mObjectGraph = ObjectGraph.create(getModules().toArray());  
        System.out.println(String.format("init object graph = %s",mObjectGraph.toString()));

    }

}

然后,在我的应用程序类中,我有这样一个构造函数:

代码语言:javascript
复制
public MyApp() {
    System.out.println("myapp construtor");  
    Injector.getInstance().initialize(this);
    Injector.getInstance().inject(this);

}

然后当我想要注射什么的时候我就做这个

代码语言:javascript
复制
@Inject Bus mBus;

public GcmBroadcastReceiver() {
    Injector.getInstance().inject(this);

}

我有两个模块,一个用于生产,一个用于测试。

生产部有这样的

代码语言:javascript
复制
@Provides @Singleton
public Bus provideBus () {
    return BusProvider.getInstance();
}

测试者有这个

代码语言:javascript
复制
@Provides @Singleton
public Bus provideBus () {
    return mock(Bus.class);
}
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25361454

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档