5

好的。让我试着把这种情况分解一下,因为我认为标题可能有点不清楚。在继续之前,我会尽可能说,我已经尝试将这个应用程序的基本结构建立在官方 dagger 示例的基础上。

本质上,我想要做的是能够将LocationClient注入我的SplashActivity,以便在LocationClient.connect()打开应用程序后立即建立连接(通过 )。

现在,很明显,LocationClient 不能通过任何类型的默认构造函数注入(它需要一些非常具体的东西(上下文和一些回调)。所以,我 @Provides在我的ActivityModule:

@Provides
@Singleton
LocationClient providesLocationClient(@ForApplication Context context, LocationService service) {
  return new LocationClient(context, service, service);
}

LocationService是我为实现所需的回调而创建的类LocationClient。我还通过@Provides我的ActivityModule

@Provides
@Singleton
LocationService providesLocationService(@ForActivity Context context, Logger logger) {
    return new LocationService(context, logger);
}

我会在最后提供所有相关文件的完整代码,以供参考。

所以,我想@InjectLocationClient我的SplashActivity. 但是,当我这样做时,我收到以下错误:

No injectable members on com.google.android.gms.location.LocationClient. Do you want to add an injectable constructor? required by class m.myapp.android.storemode.presentation.activity.SplashActivity

我发现只有两种方法可以避免这个错误,而且都不能完成我需要的。我可以

  1. 将注入移动LocationClient到片段上。这不好,因为这一点对于应用程序的流程来说太晚了。我希望能够在LocationClient此时开始调用 ,这需要建立连接。

  2. @Provides在for中删除对 Activity Context 的引用LocationService,并将@Providesfrom移动ActivityModuleAndroidModule。这也不好,因为我需要 Activity 上下文来完成回调中的一些事情(如在 Google 示例中设置新的位置服务所见)。

所以,这就是我陷入的困境。我希望这有点道理。我很难解释它,因为它太分散了。下面是 my ActivityModule、 my AndroidModule、 my Application 文件和 my的代码BaseActivity

活动模块

@Module(
    injects = {MainActivity.class,
               SplashActivity.class,
               HomeFragment.class,
               StoreLocatorFragment.class,
               BrowseProductsFragment.class,
               BrowseProductCategoriesFragment.class},
    includes = {NetworkImageModule.class, ApiModule.class, WatchListModule.class},
    complete = false
)
public class ActivityModule {

    private final BaseActivity mActivity;

    public ActivityModule(BaseActivity activity) {
        this.mActivity = activity;
    }

    /**
     * Allow the mActivity context to be injected but require that it be annotated with {@link
     * ForActivity @ForActivity} to explicitly differentiate it from application context.
     */
    @Provides
    @Singleton
    @ForActivity
    Context provideActivityContext() {
        return mActivity;
    }

    @Provides
    @Singleton
    KeyboardHider provideKeyboardHider(InputMethodManager imm) {
        return new KeyboardHider(imm);
    }

    @Provides
    ProgressDialog providesProgressDialog() {
        return new ProgressDialog(mActivity);
    }

    @Provides
    @Singleton
    LocationService providesLocationService(@ForActivity Context context, Logger logger) {
        return new LocationService(context, logger);
    }

    @Provides
    @Singleton
    LocationClient providesLocationClient(@ForApplication Context context, LocationService service) {
        return new LocationClient(context, service, service);
    }

    @Provides
    @Singleton
    PIVenueIdService providesPiVenueIdService(LocationClient locationClient) {
        return new PIVenueIdService(locationClient);
    }

}

安卓模块

@Module(library = true)
public class AndroidModule {

    /**
     * SharedPreferences name
     */
    public static final String PREFERENCE_NAME = AndroidModule.class
            .getPackage()
            .getName() +
            "Preferences";

    private final StoreModeApplication mApplication;

    //Only created for testing
    public AndroidModule() {
        mApplication = null;
    }

    public AndroidModule(StoreModeApplication application) {
        mApplication = checkNotNull(application);
    }

    /**
     * Allow the application context to be injected but require that it be annotated with {@link
     * ForApplication @Annotation} to explicitly differentiate it from an activity context.
     */
    @Provides
    @Singleton
    @ForApplication
    Context provideApplicationContext() {
        return mApplication;
    }

    @Provides
    @Singleton
    SharedPreferences provideSharedPreferences() {
        return mApplication.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
    }

    @Provides
    @Singleton
    RequestQueue provideRequestQueue() {
        return Volley.newRequestQueue(mApplication);
    }

    @Provides
    @Singleton
    ActivityManager provideActivityManager() {
        return (ActivityManager) mApplication.getSystemService(Context.ACTIVITY_SERVICE);
    }

    @Provides
    @Singleton
    LocationManager provideLocationManager() {
        return (LocationManager) mApplication.getSystemService(Context.LOCATION_SERVICE);
    }

    @Provides
    @Singleton
    Logger provideLoggingService() {
        return new LogCatLogger();
    }

    @Provides
    @Singleton
    Gson provideGson() {
        return new Gson();
    }

    @Provides
    @Singleton
    InputMethodManager provideInputMethodManager() {
        return (InputMethodManager) mApplication.getSystemService(Context.INPUT_METHOD_SERVICE);
    }

}

申请文件

public class StoreModeApplication extends Application {

    private static StoreModeApplication sInstance;

    private ObjectGraph mGraph;


    /**
     * Only use this for easy access to inject function
     */
    public static StoreModeApplication getInstance() {
        return sInstance;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        // Setup debugging for butterknife
        Views.setDebug(BuildConfig.DEBUG);

        // Create ability to get instance
        sInstance = this;

        // Setup DI
        mGraph = ObjectGraph.create(getModules().toArray());


    }


    /**
     * Used for injecting dependencies
     *
     * @param object object that needs dependencies injected
     */
    public void inject(Object object) {
        mGraph.inject(object);
    }

    /**
     * Gets mGraph.
     *
     * @return Value of mGraph.
     */
    public ObjectGraph getApplicationGraph() {
        return mGraph;
    }

    /**
     * Creates a list containing all the modules required for dagger
     */
    private List<Object> getModules() {
        return Arrays.asList(
                new AndroidModule(this),
                new ActivityObjectMapperModule(),
                new NetworkImageModule()
        );
    }

基本活动

public abstract class BaseActivity extends Activity {

    private ObjectGraph mActivityGraph;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        StoreModeApplication storeModeApplication = StoreModeApplication.getInstance();
        mActivityGraph = storeModeApplication.getApplicationGraph()
                .plus(
                        getModules().toArray()
                );

        mActivityGraph.inject(this);
    }

    @Override
    protected void onDestroy() {
        // Eagerly clear the reference to the activity graph to allow it to be garbage collected as
        // soon as possible.
        mActivityGraph = null;
        super.onDestroy();
    }

    protected List<Object> getModules() {
        return Arrays.asList(
                new ActivityModule(this),
                new StoreLocatorFragmentModule(),
                new WatchListModule()
        );
    }


    /**
     * Inject the supplied {@code object} using the activity-specific graph.
     */
    public void inject(Object object) {
        mActivityGraph.inject(object);
    }
4

1 回答 1

0

我知道这是一个老问题,但你记得用 注释 LocationService 的构造函数@Inject吗?

此外,LocationService 所需的 Logger 可能不明确,您可能还需要一个 Logger 才能provideLogger使 Dagger 能够找到该依赖项。

据我所知,唯一可能的错误来源。

于 2014-02-20T12:39:32.447 回答