在Guice中,我完全控制了构造模块的时间,并使用了一些模块和我安装的构造函数参数.
然而,在Dagger中,引用其他模块的方法是通过@Module包含注释,并没有给我提供创建要安装的模块的相同方法.
是否有可能从具有构造函数参数的多个模块创建一个理智的ObjectGraph?特别是一个可以使用匕首编译器,而不会遇到循环图的人?
好的.让我试着打破这种情况,因为我认为从标题中可能有点不清楚.在继续之前,我会尽可能地说,我试图将这个应用程序的基本结构基于官方的匕首示例.
基本上我正在尝试做的是能够将一个LocationClient注入我的SplashActivity,以便LocationClient.connect()在应用程序打开后立即建立连接(通过).
现在,显然,LocationClient不能通过任何类型的默认构造函数进行注入(它需要一些非常具体的东西(一个上下文和一些回调).所以,我在我的创建了一个 @Providesfor ActivityModule:
@Provides
@Singleton
LocationClient providesLocationClient(@ForApplication Context context, LocationService service) {
return new LocationClient(context, service, service);
}
Run Code Online (Sandbox Code Playgroud)
LocationService是我为实现所需的回调而创建的类LocationClient.我也通过@Provides我的提供ActivityModule:
@Provides
@Singleton
LocationService providesLocationService(@ForActivity Context context, Logger logger) {
return new LocationService(context, logger);
}
Run Code Online (Sandbox Code Playgroud)
我将在最后提供所有相关文件的完整代码,以供参考.
所以,我想@Inject一个LocationClient到我SplashActivity.但是,当我这样做时,我收到以下错误:
No injectable members on com.google.android.gms.location.LocationClient. Do you want to add an injectable constructor? required by class m.myapp.android.storemode.presentation.activity.SplashActivity
Run Code Online (Sandbox Code Playgroud)
我发现只有两种方法可以避免这种错误,也没有达到我的需要.我也可以
将注射移动LocationClient …
注入类的模块的一个小例子Foo:
@Module(complete = false, injects = { Foo.class })
class MyModule { }
class Foo {
@Inject
Foo(Bar bar, Baz baz) { }
}
Run Code Online (Sandbox Code Playgroud)
(假设Bar和Baz由不同的模块中提供)
我现在想Foo成为一个单身人士.
我可以添加一个@Provides方法并用@Singleton... 注释它
@Module(complete = false, injects = { Foo.class })
class MyModule {
@Provides @Singleton Foo provideFoo(Bar bar, Baz baz) {
return new Foo(bar, baz);
}
}
Run Code Online (Sandbox Code Playgroud)
...但是我必须自己编写构造函数调用,这会破坏使用注入框架的目的.有没有更短的方法来实现这一目标?
考虑一个Dagger模块:
@Module(library = true, complete = false)
public static class Module {
@Provides
public Contextualized providesContextualized(Context ctx) {
return new Contextualized(ctx.getUsername());
}
// ... and many more such provides.
}
Run Code Online (Sandbox Code Playgroud)
Context是一个对象可能连接到例如在启动时无法知道的HTTP会话,当一个人通常会创建一个图形时:
@Module(library = true, complete = false)
public static class ContextModule {
private final String username;
public ContextModule(String username) { this.username = username; }
@Provides
public Context providesContext() {
return new Context() {
public String getUsername() { return username; }
};
}
}
Run Code Online (Sandbox Code Playgroud)
鉴于Module足够长,首先为Module创建一个图表似乎是有意义的:
ObjectGraph baseline = ObjectGraph.create(new Module());
Run Code Online (Sandbox Code Playgroud)
然后,在处理特定请求时,创建一个使图形完整的唯一图形: …
我在Android上玩Dagger.我创建了一个模型UserPreference,一个调用的模块PreferenceModule和另一个类UserPreferenceTest的测试PreferenceModule.我有3个以下的java文件
UserPreference.java
package com.sigicn.preference;
import javax.inject.Inject;
import com.sigicn.commonmodels.Application;
public class UserPreference {
public String name, weiboAccount;
@Inject
public Application[] frequentlyUsedApps;
}
Run Code Online (Sandbox Code Playgroud)
然后是PreferenceModule.java
package com.sigicn.preference;
import javax.inject.Singleton;
import com.sigicn.commonmodels.Application;
import com.sigicn.utils.MiscUtils;
import dagger.Module;
import dagger.Provides;
@Module(library = true, complete = true)
public class PreferenceModule {
@Provides @Singleton UserPreference provideUserPreference() {
UserPreference userPreference = new UserPreference();
userPreference.frequentlyUsedApps = provideApplications();
return userPreference;
}
@Provides @Singleton Application[] provideApplications() {
return new Application[]{
new Application(
MiscUtils.generateUUID(), "Youtube"), …Run Code Online (Sandbox Code Playgroud) 嗨,我是新来的匕首,并试图用简单的Android应用程序研究它.
即使有注入此视图的模块,我也会从标题中收到错误.任何人都可以帮我弄清楚它为什么不注入视图?
这是我的app主要模块:
@dagger.Module(injects = {App.class, MainActivity.class}, complete = false)
public class AppModule {
private final App app;
public AppModule(App app) { this.app = app; }
@Provides @Singleton public App provideApp() { return app; }
}
Run Code Online (Sandbox Code Playgroud)
另一个注入我视图的模块:
@Layout(R.layout.sidemenu)
public class SidemenuScreen implements Blueprint{
@Override public String getMortarScopeName() { return getClass().getName(); }
@Override public Object getDaggerModule() { return new Module();}
@dagger.Module(injects= SidemenuView.class, addsTo = AppModule.class)
public static class Module {
public Module() {}
}
@Singleton public static class Presenter extends ViewPresenter<SidemenuView> …Run Code Online (Sandbox Code Playgroud) 让我们假设以下情况.应用程序的主要变体中有一个全局模块AppModule,一个作用域模块ScopedModule,一个类Main和一个类.此外,还有一个带有模块,模块和类的调试变体.只有调试变体可能知道. FooDebugAppModuleDebugScopedModuleBarBar
该主变体包含以下相关的代码片段.
@Module AppModule { /*..*/ }
@Module(injects=Main.class, addsTo=AppModule.class)
ScopedModule { @Provides Foo provideFoo() { return new Foo(); } }
class Main { scopedGraph = graph.plus(new ScopedModule(this)); }
class Foo { /*..*/ }
// In the entry point of the application
ObjectGraph.create(new AppModule());
Run Code Online (Sandbox Code Playgroud)
在调试的变体包含以下相关的代码片段.
@Module(addsTo=AppModule.class, overrides=true) DebugAppModule { /*..*/ }
@Module(injects=Main.class, addsTo=DebugAppModule.class, overrides=true)
DebugScopedModule { @Provides Foo provideFoo() { …Run Code Online (Sandbox Code Playgroud) 我是Otto的新手,我在与Dagger依赖注入器和JobManager一起完成其功能时遇到了严重的麻烦.每当我启动我的应用程序时,我都会收到相同的错误消息:
"java.lang.RuntimeException: Unable to resume activity {sdos.juanjosemelero.pruebaormlite2/sdos.juanjosemelero.pruebaormlite2.MainActivity}:
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.squareup.otto.Bus.register(java.lang.Object)' on a null object reference"
[...]
"Caused by java.lang.NullPointerException:
Attempt to invoke virtual method 'void com.squareup.otto.Bus.register(java.lang.Object)' on a null object reference".
Run Code Online (Sandbox Code Playgroud)
它引用的线是这一行:
bus.register(this);
Run Code Online (Sandbox Code Playgroud)
这是我的活动:
public class MainActivity extends ActionBarActivity {
@Inject Bus bus;
@Override
protected void onResume() {
super.onResume();
bus.register(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
bus.unregister(this);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的匕首注射模块:
@Module(
injects = {MainActivity.class}, …Run Code Online (Sandbox Code Playgroud) 我是匕首的新手,我的构造函数/方法注入似乎不起作用.不起作用意味着仍然请求注入的字段.
这是我的代码:
@Module
public class AppContextModule {
private final Context appContext;
public AppContextModule(Context appContext) {
this.appContext = appContext;
}
@Singleton
@Provides
public Context getAppContext() {
return appContext;
}
}
@Singleton
@Component(modules = {AppContextModule.class})
public interface MyComponent {
void inject(ActivitiesLifeCycleListener obj);
void inject(WebViewManager obj);
Context context();
}
public final class MyClass {
private final WeakReference<Context> mAppContext;
@Inject
public MyClass(Context context) {
this.mAppContext = context
}
}
public class MyActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyClass …Run Code Online (Sandbox Code Playgroud) 我有一个小场景,我有以下结构,我试图在baseActivity Fragment中注入片段管理器,但由于某种原因,我运气不好:(
@Singleton
@Component(modules = { AppModule.class,
ActivityModule.class,
AndroidSupportInjectionModule.class })
public interface AppComponent extends AndroidInjector<App> {
@Override
void inject(App application);
@Component.Builder interface Builder {
@BindsInstance
AppComponent.Builder application(App application);
AppComponent build();
}
}
Run Code Online (Sandbox Code Playgroud)
ActivityModule.class
@PerActivity
@ContributesAndroidInjector(modules = BaseActivityModule.class)
abstract BaseActivity baseActivity();
Run Code Online (Sandbox Code Playgroud)
BaseActivityModule.class
static final String ACTIVITY_FRAGMENT_MANAGER = "ACTIVITY_FRAGMENT_MANAGER";
@PerActivity
@Named(ACTIVITY_FRAGMENT_MANAGER)
@Provides
static FragmentManager activityFragmentManager(BaseActivity activity) {
return activity.getSupportFragmentManager();
}
Run Code Online (Sandbox Code Playgroud)
BaseAcitivity.class
public abstract class BaseActivity extends DaggerAppCompatActivity {
@Named(ACTIVITY_FRAGMENT_MANAGER)
@Inject
FragmentManager fragmentManager;
}
Run Code Online (Sandbox Code Playgroud)
所以即使我在BaseActivityModule.class中提供我的片段管理器,dagger也会抛出以下错误.我甚至尝试使用Activity而不是BaseActivity作为BaseActivityModule中的输入参数.即使这样,我也会遇到同样的问题.不确定到底是什么搞砸了.所以任何帮助都表示赞赏.提前致谢 :)
Error:(17, 8) error: [dagger.android.AndroidInjector.inject(T)] @javax.inject.Named("ACTIVITY_FRAGMENT_MANAGER") android.support.v4.app.FragmentManager cannot …Run Code Online (Sandbox Code Playgroud)