#android #retrofit #retrofit2 #dagger
#Android #модернизация #доработка2 #кинжал
Вопрос:
Я настраиваю архитектуру MVVM с помощью retrofit и dagger2, но при запуске я обнаружил это исключение
ошибка: [ComponentProcessor: ошибка ошибки] dagger.internal.codegen.ComponentProcessor не смог обработать этот интерфейс, поскольку не все его зависимости могут быть разрешены. Проверьте, нет ли ошибок компиляции или циклической зависимости с сгенерированным кодом.
AppModule.java
@Module(subcomponents = ViewModelSubComponent.class)
public class AppModule {
@Singleton
@Provides
ApiService provideService(OkHttpClient okHttpClient) {
return new Retrofit.Builder()
.baseUrl(BaseRequest.BASE_URL)
.addConverterFactory(GsonConverterFactory.create(new Gson()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient)
.build()
.create(ApiService.class);
}
@Provides
CompositeDisposable provideCompositeDisposable() {
return new CompositeDisposable();
}
@Provides
@Singleton
public StethoInterceptor getSteltho() {
return new StethoInterceptor();
}
@Provides
@Singleton
OkHttpClient provideOkHttpClient(Application application, StethoInterceptor stethoInterceptor, HttpLoggingInterceptor httpLoggingInterceptor) {
OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder();
okHttpClient.connectTimeout(CommonUtils.TIMEOUT_IN_SEC, TimeUnit.SECONDS);
okHttpClient.readTimeout(CommonUtils.TIMEOUT_IN_SEC, TimeUnit.SECONDS);
okHttpClient.addInterceptor(getIntercepter(application));
if (BuildConfig.DEBUG) {
okHttpClient.addNetworkInterceptor(stethoInterceptor);
okHttpClient.interceptors().add(httpLoggingInterceptor);
}
return okHttpClient.build();
}
public Interceptor getIntercepter(final Application application) {
Interceptor headerAuthorizationInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
if (!CommonUtils.isNetworkConnected(application)) {
Request request = chain.request();
CacheControl cacheControl = new CacheControl.Builder().maxStale(1, TimeUnit.DAYS).build();
request = request.newBuilder().cacheControl(cacheControl).build();
String rawJson = chain.proceed(request).body().string();
Log.e("TAG", String.format("req response cache raw JSON response is: %s", rawJson));
return chain.proceed(request);
} else {
CacheControl cacheControl = new CacheControl.Builder().maxAge(1, TimeUnit.HOURS).build();
Request.Builder request = chain.request().newBuilder();
request.addHeader("Accept", "application/json");
//request.addHeader("Authorization", mAuth);
request.header("Cache-Control", "public, max-age=" 90);
request.header(CACHE_CONTROL, cacheControl.toString());
Response response = chain.proceed(request.build());
return response;
}
}
};
return headerAuthorizationInterceptor;
}
@Provides
@Singleton
public HttpLoggingInterceptor httpLoggingInterceptor() {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
return httpLoggingInterceptor;
}
/*@Singleton
@Provides
ProjectRepository getrepository() {
return new ProjectRepository();
}*/
@Singleton
@Provides
ViewModelProvider.Factory provideViewModelFactory(ViewModelSubComponent.Builder viewModelSubComponent) {
return new ViewModelFactory(viewModelSubComponent.build());
}
MainActivityModule.java
@Module
public abstract class MainActivityModule {
@ContributesAndroidInjector(modules = FragmentBuildersModule.class)
public abstract MainActivity contributeMainActivity(); // @ContributesAndroidInjector(modules = FragmentBuildersModule.class)
}
FragmentBuildersModule.ktx
@Module
abstract class FragmentBuildersModule {
@ContributesAndroidInjector
internal abstract fun contributeHomeFragment(): HomeFragment
//@ContributesAndroidInjector
//abstract SeriesFragment contributeSeriesFragment();
}
ViewModelFactory.java
@Singleton
public class ViewModelFactory implements ViewModelProvider.Factory {
private final ArrayMap<Class, Callable<? extends ViewModel>> creators;
@Inject
public ViewModelFactory(ViewModelSubComponent viewModelSubComponent) {
creators = new ArrayMap<>();
// View models cannot be injected directly because they won't be bound to the owner's view model scope.
creators.put(ProjectViewModel.class, () -> viewModelSubComponent.homeViewModel());
// creators.put(ProjectListViewModel.class, () -> viewModelSubComponent.projectListViewModel());
}
@Override
public <T extends ViewModel> T create(Class<T> modelClass) {
Callable<? extends ViewModel> creator = creators.get(modelClass);
if (creator == null) {
for (Map.Entry<Class, Callable<? extends ViewModel>> entry : creators.entrySet()) {
if (modelClass.isAssignableFrom(entry.getKey())) {
creator = entry.getValue();
break;
}
}
}
if (creator == null) {
throw new IllegalArgumentException("Unknown model class " modelClass);
}
try {
return (T) creator.call();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
AppComponent.java
@Singleton
@Component(modules = {AndroidInjectionModule.class, AppModule.class, MainActivityModule.class})//, MainActivityModule.class
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
Builder application(Application application);
AppComponent build();
}
void inject(MyApplication appApplication);
}
AppInjector.java
public class AppInjector {
private static Application application;
private AppInjector() { }
public static void init(MyApplication appApplication) {
application = appApplication;
DaggerAppComponent.builder().application(appApplication).build().inject(appApplication);
appApplication.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
handleActivity(activity);
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
});
}
private static void handleActivity(Activity activity) {
if (activity instanceof HasSupportFragmentInjector) {
AndroidInjection.inject(activity);
}
if (activity instanceof FragmentActivity) {
((FragmentActivity) activity).getSupportFragmentManager()
.registerFragmentLifecycleCallbacks(new FragmentManager.FragmentLifecycleCallbacks() {
@Override
public void onFragmentCreated(FragmentManager fm, Fragment fragment, Bundle savedInstanceState) {
if (fragment instanceof Injectable) {
AndroidSupportInjection.inject(fragment);
}
}
}, true);
}
}
}
MyApplication.java
public class MyApplication extends Application implements HasActivityInjector {
private static PrefManager mPref;
private static MyApplication myApplication;
private Context context;
//private String dbUrl = "";
@Inject
DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;
public static MyApplication getInstance() {
return myApplication == null ? new MyApplication() : myApplication;
}
@Override
public void onCreate() {
super.onCreate();
this.context = this;
MultiDex.install(this);
AppInjector.init(this);
Fresco.initialize(this);
RemoteConfig.initConfig();
mPref = new PrefManager(this);
debugToolsInitilization();
}
@Override
public DispatchingAndroidInjector<Activity> activityInjector() {
return dispatchingAndroidInjector;
}
Генерирует исключение при добавлении модуля MainActivityModule
Комментарии:
1. Я не уверен, что вызывает проблему. Не могли бы вы взглянуть на другой подход? Он работает без проблем для нескольких вводимых модулей Dagger. Каждый модуль dagger предназначен для определенной группы зависимостей. Пример здесь. github.com/sreeharikv112/MyCompany Вы можете найти основные конфигурации Dagger в разделе package. src/main/java/com/myoffice/dipinject/
2. Когда я добавляю исключение исключения FragmentBuildersModule, можете ли вы сказать мне, почему это происходит? Я следую своему собственному образцу github.com/SamsetDev/Mvvm-android-master
3. Я не смогу просмотреть этот образец и углубиться. Но я почти уверен, что другая ссылка на github, которую я отправил, решает аналогичные проблемы
4. я решаю эту проблему, если вы также сталкиваетесь с такими проблемами, которые вам следует изменить в классе компонента. Вы просто меняете свой AndroidInjectionModule с AndroidSupportInjectionModule