Intereting Posts
Сбой приложения при восстановлении с фона после долгого времени Элемент, который вы запросили, недоступен для покупки – андроид в биллинге приложения После обновления до Google Play Services 9.0.0 приложение зависает в DynamiteModulesC Использование сканера отпечатков пальцев для Android для приложений Android Studio – невозможно найти действительный путь сертификации для запрошенной цели Программное обеспечение Android WebView Rendering Weird Artifact Issue Когда отображается неопределенный прогресс, входящий в библиотеку поддержки Android HelloAndroid] эмулятор-5554 отключен! Отмена запуска com.example.helloandroid.HelloAndroid! Android AutocompleteTextView с использованием ArrayAdapter и фильтра Анимация на панели инструментов Android AppCompat-v21 Кнопки управления внутри уведомлений об андроидах Обезьяна сделала мое приложение мяуком Eclipse Android AVD Emulator не отображает кнопки для пользовательского разрешения. Android WebView – классы доступа из одного iframe внутри другого iframe Обновить анимацию элемента меню в ActionBarSherlock

Кинжал 2, вводящий несколько экземпляров одного и того же типа объекта

Задний план

Я конвертирую свое приложение в архитектуру MVP и обнаружил, что Dagger 2 может быть полезен для ввода зависимостей, когда это необходимо. Моему приложению нужно общаться с двумя веб-авиями (мой собственный и сторонний api). Могут быть случаи, когда запросы на мой собственный api и сторонний api могут срабатывать одновременно. Я использую Retrofit для связи с этими apis и использования GSON для сериализации / десериализации.

Что я делал раньше

Я создал два Retrofit RestAdapters и использовал шаблон Locator для получения их при необходимости. Адаптер RestAdapter, предназначенный для моего собственного api, включает в себя GSONConverter с некоторыми настраиваемыми TypeAdapters, так как я не хочу 1: 1 десериализации JSON моего ответа в приложении. Другой RestAdapter предназначен для стороннего api и использует другой GSONConverter с определенной политикой именования полей.

проблема

Я пытаюсь использовать DI вместо Service Locator для получения моего RestAdapter (и интерфейса API). У меня есть настройка класса NetModule, как показано ниже.

@Module public class NetModule { private static final String MY_API_URL = "my_api_url"; private static final String THIRD_PARTY_API_URL = "third_party_api_url"; @Provides @Singleton Cache provideOkHttpCache(Application application) { int cacheSize = 10 * 1024 * 1024; // 10 MiB return new Cache(application.getCacheDir(), cacheSize); } @Provides @Singleton OkHttpClient provideOkHttpClient(Cache cache) { OkHttpClient client = new OkHttpClient(); client.setCache(cache); return client; } @Provides @Singleton TypeAdapter<MyClass> provideMyAPITypeAdapter() { return new TypeAdapter<MyClass>() { // implementation ignored }; } @Provides @Named("myApiGson") Gson provideGsonForMyAPI(TypeAdapter<MyClass> adapter) { return new GsonBuilder() .registerTypeAdapter(MyClass.class, adapter) .setDateFormat("yyyy-MM-dd HH:mm:ss") .create(); } @Provides @Named("thirdPartyApiGson") Gson provideGsonForThirdPartyAPI() { return new GsonBuilder() .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .create(); } @Provides @Named("myApiRestAdapter") RestAdapter provideMyRestAdapter(Gson gson, OkHttpClient okHttpClient) { return new RestAdapter.Builder() .setEndpoint(MY_API_URL) .setConverter(new GsonConverter(gson)) .setClient(new OkClient(okHttpClient)) .build(); } @Provides @Named("thirdPartyApiRestAdapter") RestAdapter provideThirdPartyRestAdapter(Gson gson, OkHttpClient okHttpClient) { return new RestAdapter.Builder() .setEndpoint(THIRD_PARTY_API_URL) .setConverter(new GsonConverter(gson)) .setClient(new OkClient(okHttpClient)) .build(); } @Provides @Singleton MyAPI provideMyAPI(RestAdapter adapter){ return adapter.create(MyAPI.class); } @Provides @Singleton ThirdPartyAPI provideThirdPartyAPI(RestAdapter adapter){ return adapter.create(ThirdPartyAPI.class); } } 

Как вы можете видеть выше в коде, NetModule имеет методы для возврата двух объектов Gson и двух объектов RestAdapter. Мои вопросы;

  1. Как я могу убедиться, что правильные зависимости вводятся при создании определенных интерфейсов RestAdapter & API? ( provideMyRestAdapter() требует, чтобы GSON возвращался из provideGsonForMyAPI() и для provideMyAPI() требуется, чтобы RestAdapter возвращался из provideMyRestAdapter() .)

  2. Как я могу убедиться, что только два экземпляра RestAdapter (один для моего api и другого для стороннего api) когда-либо создаются в течение всего срока службы приложения, поскольку создание RestAdapter считается дорогостоящим. Я использую атрибут @Named для методов, возвращающих RestAdapters. Скажем, например, при прямом @Inject("myApiRestAdapter") RestAdapter myRestadapter; зависимости к полю: @Inject("myApiRestAdapter") RestAdapter myRestadapter; Dagger 2 собирается создавать новый RestAdapter каждый раз или он будет использовать ранее созданный (например, @Singleton но для конкретного объекта)?

Я только начал использовать Dagger 2, и мое понимание того, как его использовать, может быть неправильным. Пожалуйста, поправьте меня, если я делаю что-то не так. Спасибо, что подняли этот длинный вопрос.

Solutions Collecting From Web of "Кинжал 2, вводящий несколько экземпляров одного и того же типа объекта"

Вы уже на полпути через решение. Чтобы завершить решение, попробуйте сделать следующее:

 @Provides @Named("myApiRestAdapter") RestAdapter provideMyRestAdapter(@Named("myApiGson") Gson gson, OkHttpClient okHttpClient) { return new RestAdapter.Builder() .setEndpoint(MY_API_URL) .setConverter(new GsonConverter(gson)) .setClient(new OkClient(okHttpClient)) .build(); } @Provides @Named("thirdPartyApiRestAdapter") RestAdapter provideThirdPartyRestAdapter(@Named("thirdPartyApiGson") Gson gson, OkHttpClient okHttpClient) { return new RestAdapter.Builder() .setEndpoint(THIRD_PARTY_API_URL) .setConverter(new GsonConverter(gson)) .setClient(new OkClient(okHttpClient)) .build(); } 

Чтобы убедиться, что во время жизни приложения создаются только два экземпляра ваших резервных копий, аннотируйте оба метода, обеспечивающие RestAdapter с помощью @Singleton как вы это делали с другими вашими методами. Что касается вашего другого вопроса, будет ли Dagger 2 создавать новый экземпляр RestAdapter каждый раз, когда он должен его вводить, я думаю, что он делает это точно, но я не уверен в этом.

Надеюсь это поможет!