Возможно ли использовать элементы @Inject (предоставленные через @Provides), содержащие контекст активности из базовой операции

Хорошо. Позвольте мне попытаться сломать эту ситуацию, потому что я думаю, что это, вероятно, немного непонятно из названия. Прежде чем идти дальше, я скажу, что, насколько это возможно, я попытался основывать основную структуру этого приложения на официальных примерах кинжалов .

По существу, что я пытаюсь сделать, вы можете ввести 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); } 

Я дам полный код всех соответствующих файлов в конце этого, для справки.

Итак, я хочу, чтобы @Inject LocationClient на мой 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 для LocationService и переместите @Provides из ActivityModule в AndroidModule . Это тоже не хорошо, так как мне нужен контекст активности для выполнения некоторых действий в обратных вызовах (как показано в примерах Google для настройки новых служб определения местоположения.

Итак, это дилемма, в которой я застрял. Надеюсь, что это создает некоторое подобие чувства. У меня возникли проблемы с объяснением этого, так как он настолько распространен. Ниже приведен код моего ActivityModule , моего AndroidModule , моего файла приложения и моего BaseActivity :

ActivityModule

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

Android-модуль

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

BaseActivity

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

Я знаю, что это старый вопрос, но не помните, чтобы комментировать конструктор LocationService с помощью @Inject ?

Кроме того, Logger, необходимый для LocationService, может быть неоднозначным, вам может потребоваться также обеспечить provideLogger чтобы Кинжал мог найти эту зависимость.

Насколько мне известно, возможны только возможные ошибки.

Intereting Posts
Robolectric visible () «W / InputEventReceiver: Попытка использовать пакетные входные события, но приемник входных событий уже удален». Курсор EditText в верхнем левом положении. Как разрешить пользователям просматривать и воспроизводить песни на Android, к которым у них уже есть доступ (например, через Google Play)? Ориентация камеры / изображения на Android Основанная на JSF инфраструктура для сенсорных веб-сайтов Учебники для Flurry Analytics в Android? Руководства Android API немного неясны мне об атрибуте android: onClick XML Слушайте ключевые события Webview с клавиатуры программного обеспечения в Android-активности Идентификатор регистрации android c2dm Невозможно сериализовать даты с помощью ksoap2 BitmapFactory.decodeStream (inputStream) всегда возвращает значение null, когда некоторые байты ошибочны Изображение на Android-обозревателе xroid на полноэкранном фоне Воспроизведение видео в GLSurfaceView вместо SurfaceView Отладка Eclipse: продолжайте работу после возврата? Как обрабатывать текстовое изображение для HTML и Linkify