我即将开始一个相对较大的项目并且想知道
使用这些依赖注入框架的真正好处是什么?
DI会增加应用加载时间吗?或提供任何性能价值?
Googles文档反对使用Robojuice因为它的RAM使用,这是所有DI的共同点吗?
有兴趣听取大家的意见.
新的AndroidStudio 1.1版本引入了单元测试支持.此URL http://tools.android.com/tech-docs/unit-testing-support提供了如何设置IDE以运行Android源的JUnit测试的分步说明.
这个插件https://bitbucket.org/hvisser/android-apt用于向AS提供Dagger2生成的文件,它适用于通常的Android代码,但不幸的是,没有为任何JUnit测试类生成Dagger2文件.我试着像配置依赖
androidTestApt 'com.google.dagger:dagger-compiler:2.0-SNAPSHOT'
根据android-apt插件文档但没有成功.
我认为问题出在单元测试的不同源目录中 - src/test/java而不是src/androidTest/javaandroid检测所使用的.
您能否提供任何帮助或信息如何解决这个问题?
我一直试图在ViewUtils类中注入Activity,但没有成功.我已经关注了几个不同的帖子,但我似乎无法理解我在实现中缺少的内容.
我知道这可能是下面帖子的重复,我真的为此道歉但老实说我看不出我错过了什么.这些是我发现的帖子:
我的实现如下:
AppComponent
@Component(modules = {
AppModule.class, AndroidSupportInjectionModule.class, ActivityBindingModule.class
}) @Singleton public interface AppComponent extends AndroidInjector<EmblyApp> {
@Component.Builder abstract class Builder extends AndroidInjector.Builder<EmblyApp> {}
}
Run Code Online (Sandbox Code Playgroud)
ActivityBindingModule
@Module public abstract class ActivityBindingModule {
@ContributesAndroidInjector
abstract LoginActivity loginActivity();
}
Run Code Online (Sandbox Code Playgroud)
LoginSubcomponent
@Subcomponent(modules = LoginSubcomponent.LoginActivityModule.class)
public interface LoginSubcomponent extends AndroidInjector<LoginActivity> {
@Subcomponent.Builder abstract class Builder extends AndroidInjector.Builder<LoginActivity> {}
@Module abstract class LoginActivityModule {
@Binds abstract Activity bindActivity(LoginActivity activity);
@Provides @ActivityScope static ViewUtils viewUtils(Activity activity) {
return new …Run Code Online (Sandbox Code Playgroud) 我正在努力了解@ReusableDagger范围的使用.从文档中我可以理解的是,如果提供程序的作用域@Singleton或任何其他自定义作用域,则首先创建对象,然后在组件的整个生命周期中对其进行高速缓存.因此,对于并不总是需要相同实例或不经常使用的对象,这种方法最终会浪费内存.
但是如果我们选择一个非范围的提供者,每次它都会创建一个新实例,并且由于对象实例化很昂贵,特别是在Android等环境中,分配可能很昂贵,这可能会导致性能问题.
@Reusable范围位于无范围和范围实例之间.从文档中
有时您希望限制实例化@Inject构造的类或调用@Provides方法的次数,但您不需要保证在任何特定组件或子组件的生命周期中使用完全相同的实例
它是如何工作的?假设我有一个可重用的提供程序,AppComponent它不会总是给我相同的实例吗?
如果我在任何中注入相同的依赖项Subcomponent,我将获得相同的实例吗?什么时候将为GC释放缓存的对象?
我尝试了一个示例,@Reusable在我的AppComponent模块中创建一个对象并从我的子组件中注入相同的对象.
我能看到的是它的表现完全一样@Singleton.
我们可以从中获得哪些性能改进@Reusable?
我们应该选择哪些可能的用例@Reusable?
将所有无状态对象(无论我们是否获得相同的实例)都包括在内,例如Util类,Gson,Glide等,这是一个好主意@Reusable吗?
我遇到的错误如下:
引起:java.lang.IllegalArgumentException:没有为Class绑定的进程工厂.注射器工厂被绑定为MyActivity_的超类型:[MyActivity].你的意思是绑定注射器工厂的子类型?
据我所知,这是因为我正在使用AndroidAnnotations库.
AppComponent.class:
@Singleton
@Component(modules = {
AndroidInjectionModule.class,
AppModule.class,
ActivityBindingModule.class })
public interface AppComponent extends AndroidInjector<DaggerApplication> {
@Component.Builder
interface Builder {
@BindsInstance Builder application(Application application);
AppComponent build();
}
void inject(Application application);
@Override
void inject(DaggerApplication instance);
}
Run Code Online (Sandbox Code Playgroud)
AppModule.class:
@Module
public abstract class AppModule {
@Binds
abstract Context provideContext(Application application);
@Provides
@Singleton
static SharedPreferencesManager providesPreferences(Application application){
return SharedPreferencesManager_.getInstance_(application);
}
}
Run Code Online (Sandbox Code Playgroud)
ActivityBindingModule.class:
@Module
public abstract class ActivityBindingModule {
@ContributesAndroidInjector(modules = LoginActivityModule.class)
@LoginActivityScope
abstract LoginActivity bindLoginActivity();
}
Run Code Online (Sandbox Code Playgroud)
Application.class:
@EApplication …Run Code Online (Sandbox Code Playgroud) 我意识到Lazy使用 Dagger 完成注入的推荐方法是添加Lazy到字段注入点。例如,
class Foo {
@Inject lateinit var bar: Lazy<Bar>
fun useBar() = bar.get().doSomething()
}
Run Code Online (Sandbox Code Playgroud)
使用构造函数注入怎么样?我还没有看到有人这样做。
class Foo @Inject constructor(private val fizz: Fizz,
private val bar: Lazy<Bar>) {
fun useBar() = bar.get().doSomething()
}
Run Code Online (Sandbox Code Playgroud)
总结一下,在进行 Dagger 延迟注入时,我可以Lazy<Bar>在构造函数中使用吗?或者我唯一的选择是转移Lazy<Bar>到字段注入,同时将其他非惰性依赖项保留在通过构造函数注入的同一类中?
感谢您的指点!
我有一个问题,也许有经验的人可以让我更清楚一些。我已经将Hilt模块编写为接口或抽象类。这两者之间有实际区别吗?例如,我在Hilt我的应用程序中更改了以下模块,但它仍然有效。
@Module
@InstallIn(ViewModelComponent::class)
abstract class LocalModules {
@Binds
@ViewModelScoped
abstract fun bindTemporaryImageFileFactory(factory: TemporaryImageFileFactoryImpl): TemporaryImageFileFactory
}
Run Code Online (Sandbox Code Playgroud)
或者
@Module
@InstallIn(ViewModelComponent::class)
interface LocalModules {
@Binds
@ViewModelScoped
fun bindTemporaryImageFileFactory(factory: TemporaryImageFileFactoryImpl): TemporaryImageFileFactory
}
Run Code Online (Sandbox Code Playgroud) 我正在我的测试项目中尝试 Hilt DI。我在 SingletonComponent 中安装了以下模块,就 Android 而言,它是 applicationComponent。但是,当我尝试使用 @Singleton 来确定提供方法的范围时,出现以下错误。
MyApplication_HiltComponents.ViewModelC repeats modules with scoped bindings or declarations:
public abstract static class SingletonC implements MyApplication_GeneratedInjector,
^
- com.test.catalogue.presentation.application.MyApplication_HiltComponents.SingletonC also includes:
- com.test.catalogue.di.modules.RetrofitModule with scopes: @javax.inject.Singleton
Run Code Online (Sandbox Code Playgroud)
以下是我的模块声明。
改造模块:
@Module(includes = {OKHttpModule.class})
@InstallIn(SingletonComponent.class)
public class RetrofitModule {
@Provides
@Singleton
public MyApi providesAPI(Retrofit retrofit) {
return retrofit.create(MyApi.class);
}
@Provides
@Singleton
public Retrofit providesRetrofit(OkHttpClient okHttpClient, GsonConverterFactory gsonConverterFactory, LiveDataAdapterFactory liveDataAdapterFactory) {
return new Retrofit.Builder()
.client(okHttpClient)
.addCallAdapterFactory(liveDataAdapterFactory)
.addConverterFactory(gsonConverterFactory)
.baseUrl(BuildConfig.API_URL)
.build();
}
@Provides
public GsonConverterFactory providesGsonConverterFactory() { …Run Code Online (Sandbox Code Playgroud) 我正在尝试找到如何在特定片段相关场景中定义 Hilt 的解决方案。我有以下设置:
父片段 1 使用依赖项 A。我只想在该父片段及其所有子片段之间共享该依赖项的实例。父片段 2 + 其子片段应使用与父片段 1 + 子片段不同的实例。一般来说,他的结构应该只有任何给定依赖关系的两个实例 - 一个用于第一个流,一个用于第二个流。
我可以看到自定义范围可能在这里工作,但我不确定如何在 Hilt 中使用它。
我正在尝试将数据添加到 firestore。我也想用匕首来做到这一点。但我不断收到此错误。你能帮我吗......
** 默认 FirebaseApp 在此进程 com.example.vvvv 中未初始化。确保首先调用 FirebaseApp.initializeApp(Context)。**
Firestore存储库
class FirestoreRepository @Inject constructor(private val usersRef:
CollectionReference) {
fun saveSearchResults(userEntities: List<UserEntity>) {
usersRef.add(userEntities).addOnCompleteListener { task ->
when (task.isSuccessful) {
true -> Log.d(ContentValues.TAG, "added:success")
false -> Log.d(ContentValues.TAG, "added:unsuccess")
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
视图模型
@HiltViewModel
class UserListViewModel @Inject constructor(private val repository: RoomRepository, private
val firestoreRepository: FirestoreRepository) :
ViewModel() {
private val _users = MutableLiveData<List<User>>()
val users: LiveData<List<User>>
get() = _users
var userData: MutableLiveData<List<User>> = MutableLiveData()
fun userSearch(term: String) {
viewModelScope.launch {
loadFromCache(term) …Run Code Online (Sandbox Code Playgroud) dagger ×10
android ×7
dagger-2 ×6
dagger-hilt ×3
kotlin ×2
butterknife ×1
dependencies ×1
firebase ×1
java ×1