Dagger 2 inject error in AppCompatActivity - android

I'm newbie for Dagger.
Current I create sample project some snip code:
MyComponent.java
#PerActivity
#Component(modules = MyModule.class)
public interface MyComponent {
void inject(TutorialActivity activity);
}
MyModule.java
#Module
public class MyModule {
#Provides
Position providePosition() {
return new Position();
}
}
PerActivity.java
#Scope
#Retention(RUNTIME)
public #interface PerActivity {}
TutorialActivity.java
public class TutorialActivity extends AppCompatActivity{}
When compile project I get error:
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
> java.lang.IllegalArgumentException: expected one element but was: <android.support.v4.app.FragmentActivity, android.support.v4.app.TaskStackBuilder.SupportParentable>
So if I change TutorialActivity as:
public class TutorialActivity extends Activity{}
or even
public class TutorialActivity{} // Without extends
Then it will working normally.(I can see class generated by Dagger2).
Please help !
Thanks.
UPDATE
My project structure:
common module.
app module. (app module will use common module as depended in gradle).
In both build.gradle (common and app module) I added:
apt "com.google.dagger:dagger-compiler:${daggerVersion}"
compile "com.google.dagger:dagger:${daggerVersion}"
In build.gradle at common module:
provide "org.glassfish:javax.annotation:${javaxAnnotationVersion}"
An error only occurs if I have 2 module. (module app depended on common).
If I move my Component/Module to module common -> It work.
But when I move that to app module -> Error when compile.

I'm not sure that your issue is a problem with Dagger because I don't see you requesting any dependencies in your Android components.
Nonetheless you need this in your build.gradle to use the depdendency injection annotations.
provided 'javax.annotation:jsr250-api:1.0'

Thanks #plash for your answer.
After I re-check for both module.
I found I only added:
provide "org.glassfish:javax.annotation:${javaxAnnotationVersion}"
in common module.
After I added that provide for both module then compile success.(Dagger generated class.)

Related

Dagger 2 androidx fragment incompatible types

I'm using Dagger 2.21 and when I try to do
#Module
internal abstract class FragmentModule {
#ContributesAndroidInjector
internal abstract fun loginFragment() : LoginFragment
}
and
#Singleton
#Component(modules = [AndroidSupportInjectionModule::class, AppModule::class, ActivityModule::class, ViewModelBuilder::class, ViewModelModule::class, RepositoriesModule::class, ApiModule::class, FragmentModule::class])
interface AppComponent : AndroidInjector<PhotocoApplication> {
#Component.Builder
abstract class Builder : AndroidInjector.Builder<PhotocoApplication>()
}
I get this error:
/app/build/generated/source/kapt/debug/com/photoco/app/injection/module/FragmentModule_LoginFragment$app_debug.java:18: error: incompatible types: Class LoginFragment cannot be converted to Class extends Fragment
I have been searching and saw that using 2.21 and setting this gets it to work but no luck yet
android.useAndroidX=true ; android.enableJetifier=true
LoginFragment extends:
dagger.android.support.DaggerFragment()
With all this setup can't get it to build, am I missing something here? I can make it work with Activities using DaggerActivity but not with Fragments.
PhotocoApplication extends dagger.android.support.DaggerApplication
Thanks!
Fixed this issue by updating all dagger dependencies to 2.21, was missing android-support (was still using 2.16).
implementation 'com.google.dagger:dagger:2.21'
implementation 'com.google.dagger:dagger-android:2.21'
implementation 'com.google.dagger:dagger-android-support:2.21'
kapt "com.google.dagger:dagger-compiler:2.21"
kapt "com.google.dagger:dagger-android-processor:2.21"
I just had the same problem but with two non-Android classes: EventBus and a wrapper class around Android resources.
I tried the solution proposed by Emanuel Amiguinho even it had nothing to do with android-support and it got fixed. So I tried to remove the added dependency and retry, and magically built successfully again.
So I guess in my case it was some caching issue.

java.lang.NoClassDefFoundError: dagger.internal.Preconditions android dagger2

I am switching between two project using build flavor. I am using dagger2 and one project working fine but when switching another project and trying to run it showing below error:
java.lang.NoClassDefFoundError: dagger.internal.Preconditions
at common.di.DaggerAppComponent$Builder.appModule(DaggerAppComponent.java:35)
Here is my gradle dependency:
// Dependency Injection
annotationProcessor 'com.google.dagger:dagger-compiler:2.14.1'
implementation 'com.google.dagger:dagger:2.14.1'
compileOnly 'javax.annotation:jsr250-api:1.0'
The issue is mainly when adding appModule in AppComponent.
private AppComponent createAppComponent() {
return DaggerAppComponent.builder()
.appModule(new AppModule(this)) //Problem is here
.networkModule(new NetworkModule())
.build();
}
Finally, I have found the root cause. Its basically API level issue.
For android API level below 21 you need to add following dependency in build gradle file. Also change the Application class to MultiDexApplication like below:
In app build.gradle file:
Implementation 'com.android.support:multidex:1.0.3'
In you BaseApplication change Application class to MultiDexApplication:
public class BaseApplication extends MultiDexApplication {
#Override
public void onCreate() {
super.onCreate();
}
}

Dagger's module doesn't work after conversion from Java to Kotlin

I create simple application for Android with Dagger 2. It has one shared object and one module. The module is:
#Module
public class MyModule {
#Provides
#Singleton
public Hren providesHren() {
return new Hren();
}
}
This module works. But when I convert it to Kotlin, I get compile time error:
> Task :app:compileDebugJavaWithJavac
...../DaggerMyApplicationComponent.java:26: error: cannot find symbol
DoubleCheck.provider(MyModule_ProvidesHrenFactory.create(builder.myModule));
^
symbol: variable MyModule_ProvidesHrenFactory
location: class DaggerMyApplicationComponent
1 error
This module after conversion:
#Module
class MyModule {
#Provides
#Singleton
fun providesHren(): Hren {
return Hren()
}
}
What's wrong? Why I get this error? How to solve?
Ensure you have properly configured your project to support annotations with Kotlin.
In your build.gradle(Module:app) file, check that you have applied the following settings:
apply plugin: 'kotlin-kapt'
kapt "com.google.dagger:dagger-compiler:dagger_version"
kapt "com.google.dagger:dagger-android-processor:dagger_version"
Then, clean and rebuild your project:
./gradlew clean && ./gradlew build

Dagger2 multi-module design

For Dagger2 release , i plan to split the module into few small module for re-use on other projects.
Application Module contains many things, i can group it into three type.
Type A related, Type B related, Type C related.
so i want to put it into three different module , therefore it can re-use part of it if need on other projects.
Reference from the Google's Fork
build.gradle for Application
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
mavenCentral()
}
}
build.gradle for app module
apply plugin: 'com.neenbedankt.android-apt'
//below lines go to dependenc
compile 'com.google.dagger:dagger:2.0'
apt 'com.google.dagger:dagger-compiler:2.0'
provided 'org.glassfish:javax.annotation:10.0-b28'
after above steps , i am going to create my application module
#dagger.Module
public class MyApplicationModule {
void inject(MyApplication application);
}
and my component
#Singleton
#Component(
modules = {TypeA.class, TypeB.class, TypeC.class})
public interface MyApplicationComponent {
When i use it on activity , it looks like
#Component(dependencies = MyApplicationComponent.class,
modules = ActivityModule.class)
public interface ActivityComponent {
void injectActivity(SplashScreenActivity activity);
There are compile issue
Error:(22, 10) error: XXXXXX cannot be provided without an
#Provides- or #Produces-annotated method.
com.myapplication.mXXX
[injected field of type:
XXX]
i guess there are something wrong when i config that Activity Component extends from application component.
my purpose is some singleton object inside Application Component , activity will inject same object to reduce some object create every time on activity.
is my design wrong?? or any other things need to do for config??
find out the root cause is come from #Scope
need to expose the type for other sub-component usage
#Scope
#Retention(RetentionPolicy.RUNTIME)
public #interface ActivityScope {
}
if we want to expose the Context for application ,
#Singleton
#Component(
{TypeA.class, TypeB.class, TypeC.class})
public interface MyApplicationComponent {
void inject(MyApplication application);
#ForApplication
Context appContext();
when my sub-component want to extend this
#ActivityScope
#Component(dependencies = MyApplicationComponent.class,
modules = ActivityModule.class)
public interface ActivityComponent extends MyApplicationComponent {
void injectActivity(Activity activity);
i think it is a great thing for Dagger2 , let you manually expose the object you need to use , code become more traceable.

Test Error Maven RoboGuice [No implementation for "class" was bound]

I have an Android Project which contains two source folders src and test. In test, I have my test classes and some mock classes. I'm using RoboGuice dependency injection for Android in some class I wrote tests for.
The tests run perfectly fine in Eclipse on an emulator but fail using maven clean install.
No implementation for com.Store<com.MessageEvent> was bound.
The tests fail at setUp when using the injector.
mm = Guice.createInjector(new TestModule()).getInstance(MM.class);
And here is my binding module:
public class TestModule implements Module{
#Override
public void configure(com.google.inject.Binder binder) {
binder.bind(Context.class).toInstance(getContext());
binder.bind(Scheduler.class).to(MockScheduler.class);
binder.bind(EventManager.class).to(MockEventManager.class);
binder.bind(new TypeLiteral<Store<Message>>(){}).to(new TypeLiteral<JsonStore<Message>>(){});
binder.bind(new TypeLiteral<Store<MessageEvent>>(){}).to(new TypeLiteral<JsonStore<MessageEvent>>(){});
}
#Provides
JsonStore<MessageEvent> provideMessageEventJsonStore(Context context){
return new JsonStore<MessageEvent>(context, "message_events_test.json", MessageEvent.class);
}
#Provides
JsonStore<Message> provideMessageJsonStore(Context context){
return new JsonStore<Message>(context, "message_manager_test.json", Message.class);
}
}
Why would the exception be thrown while running tests in Maven but not in Eclipse?
"No implementation was bound" means that you need to add a line for this particuar class in your modules file.

Categories

Resources