我的团队在我们的Android应用程序中采用了Dagger进行依赖注入,我必须说我们喜欢它到目前为止.但是,我们希望确保我们有效地使用它.我想知道是否有人可以解释或者是否有任何文档解释Dagger为注入依赖关系而反思的情况?
在ORMLite文档中,建议OrmLiteSqliteOpenHelper为每个活动创建.因为获取帮助程序只需要一个Context对象,为什么不为整个Application对象创建一次数据库帮助程序?这样就可以使用Dagger(或其他注入框架)将数据库助手注入需要它的类中.
有没有理由不创建一个单一的应用程序范围的数据库帮助程序?是否最好让每个活动都有自己的数据库助手?我可以想象这会使助手的缓存大小变小,因为缓存只包含与其活动相关的对象.
我有一个工作和图书馆项目.Dagger用于工作项目,几天前我决定在图书馆项目中使用Dagger.我为库项目配置了Eclipse Java Compiler和Annotation Processing设置,添加了必需的Dagger和JavaWriter JAR,在库项目中对模块进行了decalred.现在这两个项目都没有任何错误.
但是当我尝试在Android设备上运行应用程序时,它崩溃了:
java.lang.RuntimeException:
Unable to create application com.iqm.smartapp.AlarmsApplication:
java.lang.IllegalStateException:
Module adapter for class com.iqm.library.IQMLibraryModule could not be loaded.
Please ensure that code generation was run for this module.
Run Code Online (Sandbox Code Playgroud)
我认为这是因为在库项目中.apt_generated文件夹是空的!Dagger不会为库项目生成类.可能有一些IDE /项目配置错误.但是在工作和库项目中完全配置并且没有更多的想法,可能是错的.
所以我的问题是:是否有可能在Android库项目中使用Dagger?什么应该是正确的Eclipse配置启用需要代码生成?
提前致谢.
编辑:我创建了一个新的干净库项目,为Dagger设置并复制旧文件中的所有源文件.此时,新项目中的所有项目都按预期工作.奇怪的事情!
我正在试图找出实现支持OAuth2流的AccountManager.getAuthToken()的Retrofit客户端的最佳方法.我跟随U2020
理想情况下,我想在这些线上有一个简单的注射器
public class ExampleFragment extends InjectionFragment {
@Inject ApiDatabase database;
@Override public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
subscribe(database.getSomeData(), ...);
}
}
我正在考虑一个类似于示例的RequestInterceptor
public final class ApiHeaders implements RequestInterceptor {
ApiKeyProvider apiKeyProvider;
@Inject
public ApiHeaders(ApiKeyProvider apiKeyProvider) {
this.apiKeyProvider = apiKeyProvider;
}
@Override
public void intercept(RequestFacade request) {
// How to handle exceptions from getAuthToken?
request.addHeader("Authorization", "Bearer " + apiKeyProvider.getAuthKey());
}
}
和
public class ApiKeyProvider {
AccountManager accountManager;
Activity activity;
public ApiKeyProvider(Activity activity, AccountManager accountManager) {
this.activity … 我有一段时间用Dagger测试了一些东西,在监督了这里的一系列文章之后:http://antonioleiva.com/dependency-injection-android-dagger-part-1/,回去了解更多信息,我看到了一些很好的例子,比如这些:https://github.com/adennie/fb-android-dagger,其中大部分集中在注入依赖上Activity,Fragment,Service和相关的.我想和RoboGuice做类似的事情.
在RoboGuice中
public class Utils {
@InjectResource(R.string.hello_world) private String hello;
public void showLog(){
System.out.println("String from injected resource : " + hello);
}
}
Run Code Online (Sandbox Code Playgroud)
在匕首
public class Utils {
@Inject
Resources mResource;
public void showLog() {
System.out.println( "String from injected resource : " + this.mResource.getString( R.string.hello_world ) );
}
}
Run Code Online (Sandbox Code Playgroud)
我在我的应用程序中创建了一个模块
@Module( injects = {Utils.class }, complete = false, library = true )
public class ResourceModule {
Context mContext; …Run Code Online (Sandbox Code Playgroud) 我正在使用Dagger进行依赖注入,它在我的应用程序中运行良好但我无法测试它.为了创建模块依赖图,我遵循了这种模式:https://github.com/pyricau/shipfaster/blob/master/src/main/java/com/squareup/shipfaster/common/ShipFasterApplication.java
现在,在我的MainActivity测试类中,我希望能够在调用Activity onResume()方法时验证与mock的交互.
这是班级:
@Config(emulateSdk = 18)
@RunWith(RobolectricDaggerTestRunner.class)
public class MainActivityTest extends TestCase {
@Inject MainActivity sut;
public @Mock MyObject mockMyObject;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
ObjectGraph.create(new TestModule()).inject(this);
}
@Test
public void testThatMyActivityDelegatesDoSomethingToMyObject(){
//init
ActivityController<MainActivity> activityController = ActivityController.of(sut);
//run
activityController.create().start().resume();
//verify
Mockito.verify(mockMyObject).doSomething();
}
@Module(
includes = {ActivityModule.class},
injects = MainActivityTest.class,
overrides = true,
library = true
)
class TestModule {
@Provides
MyObject provideMyObject() {
return mockMyObject;
}
}
}
Run Code Online (Sandbox Code Playgroud)
从我所看到的,该onCreate()方法被调用,但使用的是真实的实例myObject,而不是被模拟的实例.测试失败了"想要但未被调用 …
我有项目A,曾经有模块A1,使用dagger v.1.2.2.现在我想添加项目A,模块A2,它依赖于dagger v.2.0.但我不能因为这两个匕首库存冲突.我可以在不同的Android模块中以某种方式处理多个版本的库吗?
Dagger2在Android工作室中没有生成任何组件类我知道它是一个已知问题,而我已经完成了几乎所有方法在我的android工作室中实现并尝试了各种教程但是每次我被击中这里,它都无法构建dagger组件上课.我也尝试重建,清理渐变并使缓存无效,但它没有帮助.这是我的示例项目build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
android {
compileSdkVersion 25
buildToolsVersion "25.0.0"
defaultConfig {
applicationId "com.example.g.daggerillkillu"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
repositories{
maven{url "https://jetpack.io"}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.0'
testCompile 'junit:junit:4.12'
compile 'com.google.dagger:dagger:2.0.2'
apt 'com.google.dagger:dagger-compiler:2.0.2'
provided …Run Code Online (Sandbox Code Playgroud) 我有一个名为的ViewModel RecipesViewModel.通常,我这样实例化:
RecipesViewModel viewModel = ViewModelProviders.of(this, new ViewModelProvider.Factory() {
@Override
public <T extends ViewModel> T create(Class<T> modelClass) {
return (T) new RecipesViewModel(recipesRepository);
}
}).get(RecipesViewModel.class);
Run Code Online (Sandbox Code Playgroud)
但是现在我正在使用dagger2,所以我@Inject在这个ViewModel的构造函数上添加了一个注释,所以我可以使用字段注入器将它直接注入到我的片段中.
我的问题是:我是否以这种方式失去了以某种方式启动视图模型的东西ViewModelProviders.of?我的ViewModel已经被Scoped,因此在上下文中只创建一个实例.
其他选项是仅将工厂实例化移动到dagger2模块,但如果没有问题,我更喜欢第一个方法.
- 编辑 -
阅读文档android.arch.lifecycle.ViewModel,我有点害怕.使用ViewModelProviders.of提供Scope(片段或活动).如果我直接实例化它将是什么范围?
ViewModel是一个负责准备和管理Activity或Fragment数据的类.它还处理Activity/Fragment与应用程序其余部分的通信(例如,调用业务逻辑类).
始终与范围(片段或活动)关联创建ViewModel,并且只要范围处于活动状态,就会保留ViewModel.例如,如果它是一个活动,直到它完成.
换句话说,这意味着如果ViewModel的所有者因配置更改(例如旋转)而被销毁,则不会销毁它.所有者的新实例将重新连接到现有的ViewModel.
- /编辑 -
RecipesViewModel代码如下所示:
@PerActivity
public class RecipesViewModel extends ViewModel {
private static final String TAG = "RecipesViewModel";
private final RecipesRepository recipesRepository;
private LiveData<List<Recipe>> recipes = null;
@Inject
public RecipesViewModel(RecipesRepository recipesRepository) {
this.recipesRepository = recipesRepository;
}
public final void …Run Code Online (Sandbox Code Playgroud) 我将Dagger v2.12与dagger-android-support以下配置一起使用:
@Singleton
@Component(
modules = arrayOf(
AndroidSupportInjectionModule::class,
AndroidBindingModule::class,
AppModule::class
)
)
interface AppComponent : AndroidInjector<App> {
@Component.Builder
abstract class Builder : AndroidInjector.Builder<App>()
}
Run Code Online (Sandbox Code Playgroud)
@Module
abstract class AndroidBindingModule {
@PerActivity
@ContributesAndroidInjector(modules = arrayOf(MainModule::class))
internal abstract fun contributeMainActivityInjector(): MainActivity
}
Run Code Online (Sandbox Code Playgroud)
@Module
class MainModule {
...
@Provides @PerActivity
fun providePresenter(rxLifecycle: ReactiveLifecycle, view: MainView) =
MainPresenter(rxLifecycle, view)
}
Run Code Online (Sandbox Code Playgroud)
class MainActivity : BaseActivity() {
@Inject
lateinit var presenter: MainPresenter
...
}
Run Code Online (Sandbox Code Playgroud)
在分析内存转储时,我注意到MainPresenter该类已经创建了两次,其中一个在MainActivity和dagger.internal.DoubleCheck(如预期的那样) …
android ×10
dagger ×10
dagger-2 ×3
java ×3
android-architecture-components ×1
gradle ×1
kotlin ×1
oauth-2.0 ×1
ormlite ×1
retrofit ×1
roboguice ×1
robolectric ×1
unit-testing ×1