我有一个Android应用程序,我正在尝试使用匕首.我决定使用全局图+活动图.我有三个模块:
AndroidModule
@Module(library = true)
public class AndroidModule {
private final MApplication mApplication;
public AndroidModule(MyApplication application) {
mApplication = application;
}
@Provides @Singleton @ForApplication Context provideApplicationContext() {
return mApplication;
}
}
Run Code Online (Sandbox Code Playgroud)
MyAppModules
@Module(
injects = {
MainActivity.class,
AddFragment.class,
AddMapFragment.class,
MyActivity.class,
ListFragment.class,
MyMapFragment.class,
RetainFragment.class,
SingleActivity.class,
UserActivity.class,
UserLoginFragment.class,
UserProfileActivity.class,
UserProfileFragment.class,
UserRegisterFragment.class,
WelcomeFragment.class
},
complete = false,
library = true,
includes = ActivityModule.class
)
public class MyAppModule {
private final Bus mBus = new Bus();
@Provides @Singleton Bus provideBus() {
return mBus;
} …Run Code Online (Sandbox Code Playgroud) 我在 android 应用程序中使用 Dagger 来提供应用程序和活动范围图。我正在使用 Robolectric 进行单元测试。我知道我可以为 Robolectric 提供一个替代的 Application 类,该类配置了一个应用程序对象图,用模拟覆盖真实的应用程序对象图。但是我对如何对活动对象图做同样的事情感到困惑,因为活动对象图的标准模式是让活动本身实例化他们需要的特定于活动的 Dagger 模块。任何建议将不胜感激。
我有一个Mortar应用程序,MortarActivityScope是根范围内的第一个孩子.MortarActivityScope有一个ActivityScope,@为注入类提供一个活动:
@Module(addsTo = ApplicationModule.class, injects = {Foo.class, SomePresenter.class, AnotherPresenter.class})
public class ActivityModule {
private final Activity activity;
public ActivityModule(Activity activity) {
this.activity = activity;
}
@Provides Activity provideActivity() {
return activity;
}
}
public class Foo {
private final Activity activity;
@Inject(Activity activity) {
this.activity = activity;
}
public void doSomethingWithActivity() {
// do stuff with activity: findViewById(), getWindow(), mess with action bar etc.
}
}
Run Code Online (Sandbox Code Playgroud)
这种情况很好,直到方向发生变化.在Mortar示例项目中,不会在方向更改时销毁活动范围.这可能是为了让@Singleton演示者,屏幕等能够在方向变化中持续存在.您可以在示例项目的主要活动中的onDestroy()方法中看到这一点:
@Override protected void onDestroy() {
super.onDestroy();
actionBarOwner.dropView(this);
// activityScope may be null in …Run Code Online (Sandbox Code Playgroud) 我试图将SettingsPresenter提供给SettingsActivity(View)并得到"dagger类无法用键绑定"错误,请帮我修复它并弄清楚错误的原因.
错误:
Error:(32, 8) error: presenter.ISettingsPresenter could not be bound with key presenter.ISettingsPresenter required by ui.activity.settings.SettingsActivity for dagger.AppModule
Run Code Online (Sandbox Code Playgroud)
ModelsModule提供securityModel和userModel,它工作正常;
我的代码是:
SettingsActivity:
SettingsActivity implements ISettingsView {
@Inject ISettingsPresenter presenter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...
createScopedGraph(new SettingsModule(this)).inject(this);
presenter.onCreate();
//...
}
public ObjectGraph createScopedGraph(Object... modules) {
return objectGraph.plus(modules);
}
}
Run Code Online (Sandbox Code Playgroud)
的AppModule:
@Module(
injects = {
App.class,
},
includes = {
AnalyticsModule.class,
ModelsModule.class
})
public class AppModule {
private App app;
public AppModule(App app) {
this.app = app;
}
Run Code Online (Sandbox Code Playgroud)
SettingsModule:
@Module( …Run Code Online (Sandbox Code Playgroud) 反序列化时,Jackson 将从@JacksonInject提供给 的映射中获取标记为 的对象的任何属性的值,ObjectMapper而不是从 JSON 中获取。这个映射是通过调用ObjectMapper.setInjectableValues() 和提供一个InjectableValues对象来指定的 ,该对象可以查找要根据请求注入的值。
使用 Guice 创建这样的对象相当容易(就像jackson-module-guice那样)。首先,当您创建对象映射器时,您注入Injector并将其包装在一个InjectableValues实现中,该实现只是将请求转发到Injector(要注入的事物的类及其注释可用)。
为了在 Dagger 2 中实现这一点,我们需要能够获取一个Class对象(和相关的注释)并在运行时注入一个实例。然而,考虑到 Dagger 2 的代码生成方法,这似乎是不可能的。我错过了什么吗?
我想在我的项目的不同部分注入Google api客户端的实例,但是我没有设法让它工作.
@Provides @Named("geodata_api")
@Singleton
GoogleApiClient providesGoogleApiClient(Context context) {
return new GoogleApiClient.Builder(context)
.addApi(Places.GEO_DATA_API)
.build();
}
Run Code Online (Sandbox Code Playgroud)
@Provides @Named("location_api")
@Singleton
GoogleApiClient providesGoogleApiClient(Context context) {
return new GoogleApiClient.Builder(providesContext())
.addApi(LocationServices.API)
.build();
}
Run Code Online (Sandbox Code Playgroud) 假设我有一个模块,我只想导出一个实例A.但是,这A需要在构造函数中传递B和C传递实例.所以我们也会在模块中声明它们:
public class SampleModule {
@Provides
@Singleton
A provideA(B b, C c){
return new A(b, c);
}
@Provides
@Singleton
B provideB(){
return new B();
}
@Provides
@Singleton
C provideC(){
return new C();
}
}
Run Code Online (Sandbox Code Playgroud)
这工作,但现在B并C也可在代码的其他地方.我希望将它们保密,并强制客户端类只能访问A.
有没有办法实现这个目标?
在使用kotlin在项目中添加com.google.dagger:dagger-android-support依赖项后,我收到此gradle错误.
这是我的构建gradle build.gradle的一部分
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'realm-android'
apply plugin: 'me.tatarka.retrolambda'
apply plugin: 'kotlin-kapt'
android {
...
kapt {
generateStubs = true
}
}
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'
})
...
kapt "com.google.dagger:dagger-compiler:${daggerVersion}"
kapt "com.google.dagger:dagger-android-processor:${daggerVersion}"
compile "com.google.dagger:dagger:${daggerVersion}"
compile "com.google.dagger:dagger-android-support:${daggerVersion}"
...
}
Run Code Online (Sandbox Code Playgroud)
这里是我得到的 gradle错误
ApplicationComponent.java:21: error: [dagger.android.AndroidInjector.inject(T)] java.util.Map<java.lang.Class<? extends android.support.v4.app.Fragment>,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends android.support.v4.app.Fragment>>> cannot be provided without an @Provides-annotated method.
e:
public interface ApplicationComponent {
e: ^ …Run Code Online (Sandbox Code Playgroud) 对于我当前的项目,我正在使用Kotlin和Dagger 2.我想在辅助构造函数中注入依赖项,但构造函数永远不会被初始化.
class SelectionFragmentModel ():ViewModel(){
lateinit var channelInfosRepository: ChannelInfosRepository
@Inject constructor(channelInfosRepository: ChannelInfosRepository) : this(){
this.channelInfosRepository = channelInfosRepository
}
...
}
Run Code Online (Sandbox Code Playgroud)
作为一种解决方法,我目前正在主要构造函数中注入,但这不是最佳的.
class SelectionFragmentModel @Inject constructor(private val channelInfosRepository: ChannelInfosRepository):ViewModel(){
constructor() : this(ChannelInfosRepository())
...
}
Run Code Online (Sandbox Code Playgroud)
我错过了什么吗?
以前使用Dagger 2.10时,我使用了一个非常典型的设置,ActivitySubcomponent其中有一个ActivityModule,该Activity实例将实例提供给图形/将其暴露给图,以注入到需要它的其他类中。
用ActivityModule这样的:
@Module
public class ActivityModule {
private final Activity activity;
public ActivityModule(Activity activity) {
this.activity = activity;
}
/**
* Expose the activity to the graph.
*/
@Provides @ActivityScope
Activity activity() {
return activity;
}
}
Run Code Online (Sandbox Code Playgroud)
可以Activity通过ActivityModule在注入之前创建一个新的实例来获取实例:
@Inject PermissionsHelper permissionsHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DaggerApplicationComponent.builder()
.applicationModule(new ApplicationModule(getApplicationContext()))
.plus(new ActivityModule(this))
.inject(this);
}
Run Code Online (Sandbox Code Playgroud)
我可以提供Activity以下内容:
@ActivityScope
public class PermissionsHelper {
private final Activity activity; …Run Code Online (Sandbox Code Playgroud) dagger ×10
android ×8
dagger-2 ×6
java ×2
kotlin ×2
jackson ×1
mortar ×1
mvp ×1
robolectric ×1
square-flow ×1
unit-testing ×1