我有一些分析包装器,我必须在每个类中创建一个实例,如下所示:
Analytics.create(MyClass.class)
Run Code Online (Sandbox Code Playgroud)
这样构建的对象就可以使用类名来编写更好的事件.
但是为每个类创建这样的对象是非常烦人的(并且容易出错),所以我想到了使用Dagger(或Dagger2).
有没有办法可以将当前类注入已经注入的对象?更好的是,注入命名记录器的好方法是什么?
请帮助我将 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 - Android 有一段时间了,并设置了我的整个依赖关系图。我正在使用范围、限定符,所有这些好东西。我不再是 Dagger 新手了,但可以说我一直在我的 Android 设置中以非常标准的方式使用它,一切都进展顺利。
我第一次意识到我想自己手动请求图形中某个类的新实例,并且我希望它每次都是一个新实例。
这样做的最佳方法是什么?我想知道是否有办法利用非@Singleton/非作用域提供者并create()自己调用某种方法,或者最好自己创建一个工厂并使该工厂成为单例/作用域实例并使用我的工厂在我需要时获取新实例?[我应该提到这个类绝对不会有一个空的构造函数,所以需要注入在我的注入图中定义的其他类的实例。]
(此外,如果答案是在 Android 的上下文中,它可能会最有帮助;也就是说,我在一个 ViewModel 中,并且需要在我的一个模块中定义的某个类的新实例。)
我有这个Dagger 2配置:
AppComponent.kt
@Singleton
@Component(
modules = [
AndroidSupportInjectionModule::class,
AppModule::class,
ActivityBindingModule::class,
]
)
interface AppComponent : AndroidInjector<AppApplication> {
@Component.Builder
abstract class Builder : AndroidInjector.Builder<AppApplication>()
}
Run Code Online (Sandbox Code Playgroud)
ActivityBindingModule.kt
@Module
abstract class ActivityBindingModule {
@ActivityScoped
@ContributesAndroidInjector(
modules = [
MainActivityModule::class,
FragmentModule::class //a fragment factory for each activity
]
)
internal abstract fun mainActivity(): MainActivity
}
Run Code Online (Sandbox Code Playgroud)
MainActivityModule.kt
@Module(subcomponents = [LoginFragmentSubcomponent::class])
abstract class MainActivityModule {
//uncommenting this works fine but Fragment can't be scoped
//@Binds
//@IntoMap
//@FragmentKey(LoginFragment::class)
//abstract fun bindLoginFragment(loginFragment: LoginFragment): Fragment
//...other things which …Run Code Online (Sandbox Code Playgroud) 我在使用 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) 上次我尝试从 kapt 迁移到 ksp,所有库都没有问题,而不是 dagger... 参见库
dagger2_版本'2.47'
我收到错误日志:e: [ksp] 使用 KSP 编译时无法使用旧版 dagger.spi.BindingGraphPlugin:Dagger/Android/DuplicateAndroidInjectors。使用 KAPT 进行编译或迁移插件以实现 dagger.spi.model.BindingGraphPlugin。e: KSP 发生错误,查看日志了解详细信息
有人有类似的问题吗?我找不到任何东西