请帮助我将 Dagger 2 连接到 Kotlin。\n我的应用程序构建 gradle:
\n\napply plugin: \'com.android.application\'\napply plugin: \'kotlin-android\'\napply plugin: \'kotlin-android-extensions\'\napply plugin: \'io.fabric\'\napply plugin: \'kotlin-kapt\'\n\nandroid {\n compileSdkVersion 28\n defaultConfig {\n applicationId "mobile.socialboards.com"\n minSdkVersion 21\n targetSdkVersion 28\n versionCode 19\n versionName \'1.0\'\n testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"\n }\n buildTypes {\n release {\n minifyEnabled false\n proguardFiles getDefaultProguardFile(\'proguard-android.txt\'), \'proguard-rules.pro\'\n }\n debug {\n minifyEnabled false\n }\n }\n configurations {\n cleanedAnnotations\n compile.exclude group: \'org.jetbrains\' , module:\'annotations\'\n }\n productFlavors {}\n compileOptions {\n sourceCompatibility JavaVersion.VERSION_1_8\n targetCompatibility JavaVersion.VERSION_1_8\n }\n kotlinOptions {\n jvmTarget = \'1.8\'\n freeCompilerArgs = [\'-Xjvm-default=enable\']\n }\n lintOptions …Run Code Online (Sandbox Code Playgroud) 我在我的项目中使用 Dagger 2。我在项目中有几个模块。我有一个连接到每个活动模块的 BaseActivityModule。如何在 BaseActivityModule 中获取 AppCompatActivity。
编译项目时,出现此错误
错误:[Dagger/MissingBinding] [dagger.android.AndroidInjector.inject(T)] android.app.AlertDialog 不能在没有 @Inject 构造函数或 @Provides-annotated 方法的情况下提供。公共抽象接口 AppComponent { ^ android.app.AlertDialog 在 com.example.laptop.daggerexample.ui.main.view.MainActivity.alertDialog com.example.laptop.daggerexample.ui.main.view.MainActivity 在 dagger 处注入.android.AndroidInjector.inject(T) 组件路径:com.example.laptop.daggerexample.di.component.AppComponent ? com.example.laptop.daggerexample.di.builder.ActivityBuilder_BindMainActivity.MainActivitySubcomponent
项目中的以下模块示例
活动生成器
@Module
abstract class ActivityBuilder {
@ContributesAndroidInjector(modules = [(MainActivityModule::class)])
abstract fun bindMainActivity(): MainActivity
}
Run Code Online (Sandbox Code Playgroud)
应用模块
@Module
abstract class AppModule{
@Provides
@Singleton
fun provideContext(application: Application): Context = application
}
Run Code Online (Sandbox Code Playgroud)
基本活动模块
@Module
class BaseActivityModule {
@Provides
fun provideAlertDialog(activity: AppCompatActivity)=
AlertDialog.Builder(activity).create()
}
Run Code Online (Sandbox Code Playgroud)
主活动模块
@Module(includes = [(BaseActivityModule::class)])
class MainActivityModule {
@Provides
fun provideMainMVPView(activity: MainActivity): …Run Code Online (Sandbox Code Playgroud) 有趣的是,找到这个答案是多么困难。
我已经使用 Dagger - Android 有一段时间了,并设置了我的整个依赖关系图。我正在使用范围、限定符,所有这些好东西。我不再是 Dagger 新手了,但可以说我一直在我的 Android 设置中以非常标准的方式使用它,一切都进展顺利。
我第一次意识到我想自己手动请求图形中某个类的新实例,并且我希望它每次都是一个新实例。
这样做的最佳方法是什么?我想知道是否有办法利用非@Singleton/非作用域提供者并create()自己调用某种方法,或者最好自己创建一个工厂并使该工厂成为单例/作用域实例并使用我的工厂在我需要时获取新实例?[我应该提到这个类绝对不会有一个空的构造函数,所以需要注入在我的注入图中定义的其他类的实例。]
(此外,如果答案是在 Android 的上下文中,它可能会最有帮助;也就是说,我在一个 ViewModel 中,并且需要在我的一个模块中定义的某个类的新实例。)
我在使用 dagger 2.2 实现 MultiBinding 时遇到了一个问题。我正在使用带有 MVVM 架构的匕首。我已经注入了ViewModelProvideFactory构造函数并绑定了模块的依赖项。
我遵循了 youtube 上 Mitch 的教程
https://www.youtube.com/watch?v=DToD1W9WdsE&list=PLgCYzUzKIBE8AOAspC3DHoBNZIBHbIOsC&index=13
我已经在这些链接上搜索了解决方案,但仍然面临同样的问题。
Dagger2:如果没有 @Provides 注释的方法,就无法提供 ViewModel
https://github.com/google/dagger/issues/1478
代码片段
视图模型键
@MapKey
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewModelKey {
Class<? extends ViewModel> value();
}
Run Code Online (Sandbox Code Playgroud)
视图模型工厂模块
/**
* ViewModelFactoryModule responsible for providing [ViewModelProviderFactory]
*
* Annotated with Module to tell dagger it is a module to provide [ViewModelProviderFactory]
*
* Annotated with bind annotation to efficiently provide dependencies similar to provides …Run Code Online (Sandbox Code Playgroud) 我有 1 个应用程序和 1 个活动、1 个父组件和 1 个子组件的以下(简化)设置:
应用:
public class ExampleApp extends Application {
private AppComponent component;
@Override
public void onCreate() {
super.onCreate();
component = DaggerAppComponent.create();
}
public AppComponent getAppComponent() {
return component;
}
}
Run Code Online (Sandbox Code Playgroud)
应用组件:
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
ActivityComponent.Builder getActivityComponentBuilder();
}
Run Code Online (Sandbox Code Playgroud)
活动子组件:
@PerActivity
@Subcomponent(modules = {ActivityModule1.class, ActivityModule2.class})
public interface ActivityComponent {
void inject(MainActivity mainActivity);
@Subcomponent.Builder
interface Builder {
@BindsInstance
Builder binding1(@Named("binding1") int binding1);
@BindsInstance
Builder binding2(@Named("binding2") int binding2);
ActivityComponent build(); …Run Code Online (Sandbox Code Playgroud) After recently migrating from Dagger to Hilt I started observing very strange behavior with respect to ViewModels. Below is the code snippet:
@HiltAndroidApp
class AndroidApplication : Application() {}
@Singleton
class HomeViewModel @ViewModelInject constructor() :
ViewModel() {}
@AndroidEntryPoint
class HomeFragment : Fragment(R.layout.fragment_home) {
private val homeViewModel by viewModels<HomeViewModel>()
override fun onResume() {
super.onResume()
Timber.i("hashCode: ${homeViewModel.hashCode()}")
}
}
@AndroidEntryPoint
class SomeOtherFragment : Fragment(R.layout.fragment_home) {
private val homeViewModel by viewModels<HomeViewModel>()
override fun onResume() {
super.onResume()
Timber.i("hashCode: ${homeViewModel.hashCode()}")
}
}
Run Code Online (Sandbox Code Playgroud)
The value of hashCode …
当使用Robolectric和Dagger Hilt启动片段时,后期初始化字段不会注入片段中。
我有以下测试:
@RunWith(RobolectricTestRunner::class)
@HiltAndroidTest
@Config(application = HiltTestApplication::class)
class SampleTest {
@Test
fun checkFragmentProperty() {
launchFragmentInHiltContainer<TestFragment> {
// nothing
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的 TestFragment 看起来像这样:
@AndroidEntryPoint
class TestFragment : Fragment() {
@Inject
lateinit var testClass: TestClass
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
testClass.some()
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试运行此测试时,它显示错误kotlin.UninitializedPropertyAccessException: lateinit property testClass has not been initialized
我使用官方文档launchFragmentInHiltContainer中的方法,但当我只使用.lunchFragmentInContainerandroidx.fragment.app.testing
当我使用模拟器而不是 Robolectric 时,字段会被正确注入。
我尝试添加:
hilt {
enableTransformForLocalTests = true
}
Run Code Online (Sandbox Code Playgroud)
并从控制台运行测试,但测试仍然失败
我想使用拦截器刷新我的令牌,但我的拦截器需要 API 服务来进行 API 调用。我陷入了依赖循环。
这是我的 ApplicationModule 类:
@Module
@InstallIn(ApplicationComponent::class)
class ApplicationModule {
@Provides
fun providerBaseUrl() = AppConstants.BASE_URL
@Provides
@Singleton
fun provideOkHttpClient(authInterceptor: AuthInterceptor,
networkInterceptor: NetworkInterceptor) = if (BuildConfig.DEBUG) {
val loggingInterceptor = HttpLoggingInterceptor()
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
OkHttpClient.Builder()
.addInterceptor(authInterceptor)
.addInterceptor(loggingInterceptor)
.addInterceptor(networkInterceptor)
// .addInterceptor(refreshTokenInterceptor) // I want to put my interceptor here
.connectTimeout(2, TimeUnit.MINUTES)
.readTimeout(2, TimeUnit.MINUTES)
.writeTimeout(2, TimeUnit.MINUTES)
.build()
} else OkHttpClient
.Builder()
.connectTimeout(2, TimeUnit.MINUTES)
.readTimeout(2, TimeUnit.MINUTES)
.writeTimeout(2, TimeUnit.MINUTES)
.addInterceptor(authInterceptor)
.addInterceptor(networkInterceptor)
.build()
@Provides
@Singleton
fun provideRetrofit(
okHttpClient: OkHttpClient,
BASE_URL: String
): Retrofit =
Retrofit.Builder() …Run Code Online (Sandbox Code Playgroud) 我的问题非常简单明了:两个注释/示例有什么区别:
@Singleton
class MySingletonClass() {}
@Module
@InstallIn(FragmentComponent::class)
abstract class MyFragmentModule {
@Provides
fun provideMySingletonClass() = MySingletonClass()
}
Run Code Online (Sandbox Code Playgroud)
class MySingletonClass() {}
@Module
@InstallIn(FragmentComponent::class)
abstract class MyFragmentModule {
@Singleton
@Provides
fun provideMySingletonClass() = MySingletonClass()
}
Run Code Online (Sandbox Code Playgroud)
我知道的唯一区别是,第二个示例给出了以下错误:
error: [Dagger/IncompatiblyScopedBindings] FragmentC scoped with @dagger.hilt.android.scopes.FragmentScoped may not reference bindings with different scopes:
Run Code Online (Sandbox Code Playgroud)
这是否意味着@Singleton示例一中的注释被简单地忽略了?
上次我尝试从 kapt 迁移到 ksp,所有库都没有问题,而不是 dagger... 参见库
dagger2_版本'2.47'
我收到错误日志:e: [ksp] 使用 KSP 编译时无法使用旧版 dagger.spi.BindingGraphPlugin:Dagger/Android/DuplicateAndroidInjectors。使用 KAPT 进行编译或迁移插件以实现 dagger.spi.model.BindingGraphPlugin。e: KSP 发生错误,查看日志了解详细信息
有人有类似的问题吗?我找不到任何东西