There is my GitHub project - https://github.com/alekseytimoshchenko/MVVM_FLOW that I haven't used a lot of time and today I decided to check it out as a result I faced some compile/Gradle/build issues, so I needed to update some dependency and other things. Eventually looks like everything is ok, however, I got a compile
error: cannot find symbol
import com.example.krokosha.quizyourself.di.components.DaggerAppComponent;
This likely happens due to some specific dependencies or their version, I went through a few answers here on SO, but looks like everything is correct, but still, this class is not generated.
If it is suitable you are welcome to take a look at the project by the ref provided above, otherwise, I'll put some code here
There are my grale dependencies
...
//Dependency Injection
api "com.google.dagger:dagger:2.35.1"
annotationProcessor "com.google.dagger:dagger-compiler:2.28.3"
api "com.google.dagger:dagger-android:2.35.1"
api "com.google.dagger:dagger-android-support:2.28.3" // if you use the support libraries
annotationProcessor "com.google.dagger:dagger-android-processor:2.28.3"
...
and there is my class where I got an error:
package com.example.krokosha.quizyourself.di;
import android.content.Context;
import com.example.krokosha.quizyourself.di.components.AppComponent;
import com.example.krokosha.quizyourself.di.components.BaseComponent;
import com.example.krokosha.quizyourself.di.components.BaseComponentBuilder;
import com.example.krokosha.quizyourself.di.components.DaggerAppComponent;
import com.example.krokosha.quizyourself.di.moduls.AppModule;
import com.example.krokosha.quizyourself.di.moduls.BaseModule;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Provider;
public class ComponentsHolder
{
private final Context context;
#Inject
Map<Class<?>, Provider<BaseComponentBuilder>> builders;
private Map<Class<?>, BaseComponent> components;
private AppComponent appComponent;
public ComponentsHolder(Context context)
{
this.context = context;
}
public ComponentsHolder init()
{
appComponent = DaggerAppComponent.builder().appModule(new AppModule(context)).build();
appComponent.injectComponentsHolder(this);
components = new HashMap<>();
return this;
}
public BaseComponent getBaseComponent(Class<?> cls)
{
return getBaseComponent(cls, null);
}
public BaseComponent getBaseComponent(Class<?> cls, BaseModule module)
{
BaseComponent component = components.get(cls);
if (component == null)
{
BaseComponentBuilder builder = builders.get(cls).get();
if (module != null)
{
builder.module(module);
}
component = builder.build();
components.put(cls, component);
}
return component;
}
public void releaseBaseComponent(Class<?> cls)
{
components.put(cls, null);
}
}
What is a possible problem here?
DaggerAppComponent is the file Dagger generates as an implementation of your AppComponent interface. If DaggerAppComponent is not being generated, it usually means that Dagger has emitted an error that you can read further up in your compiler log. If you see one of those errors, please edit it into your question.
Also, note that you're mismatching your Dagger versions: your libraries are 2.35.1 but your annotation processor is 2.28.3. In some cases this mismatch can cause a compilation failure, though it's more typical for it to cause the generated DaggerAppComponent file to fail to compile within the generated code. (The generated code calls the dagger libraries at runtime, so if the versions don't match the generated code might call into a class or method that doesn't exist.) Because DaggerAppComponent is missing entirely, it's less likely that the version skew is the root cause of your error here, but in any case you should always have all your Dagger versions consistent: api/implementation/annotationProcessor and between dagger and dagger.android.
Related
When I updated my project to androidx then I've got following error
I also searched but can't find my answer, although project works fine
#RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
#Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.example.villagefoodsecrets", appContext.getPackageName());
}
}
At this point, #RunWith(AndroidJUnit4.class) shows that it is deprecated.
And Context appContext = InstrumentationRegistry.getTargetContext();
.getTargetContext; is in red format looks like not existed. So what can I do here - should I just ignore this?
To use non-deprecated classes, add below in build.gradle (app module level)
androidTestImplementation ‘androidx.test.ext:junit:1.1.1’
Then replace below deprecated imports in ExampleInstrumentedTest class
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
with
import androidx.test.platform.app.InstrumentationRegistry ;
import androidx.test.ext.junit.runners.AndroidJUnit4;
and to get a context use below:
for Java
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
For Kotlin
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
wish this helps you
there, i need help, im a .NET developer, but now i want to try android.
i downloaded a project from here : https://github.com/gahfy/MVVMPosts
im having problems with the BaseViewModel.kt.
i know that DaggerViewMOdelInjector is created by dagger 2 with my interface ViewModelInjector, but it is not created and i cannot build the project, please help me !!
package net.gahfy.mvvmposts.base
import android.arch.lifecycle.ViewModel
import net.gahfy.mvvmposts.injection.component.DaggerViewModelInjector
import net.gahfy.mvvmposts.injection.component.ViewModelInjector
import net.gahfy.mvvmposts.injection.module.NetworkModule
import net.gahfy.mvvmposts.ui.post.PostListViewModel
import net.gahfy.mvvmposts.ui.post.PostViewModel
abstract class BaseViewModel:ViewModel(){
private val injector: ViewModelInjector = DaggerViewModelInjector
.builder()
.networkModule(NetworkModule)
.build()
init {
inject()
}
/**
* Injects the required dependencies
*/
private fun inject() {
when (this) {
is PostListViewModel -> injector.inject(this)
is PostViewModel -> injector.inject(this)
}
}
}
update like:-
implementation "com.google.dagger:dagger:$dagger2_version"
kapt "com.google.dagger:dagger-compiler:$dagger2_version"
annotationProcessor "com.google.dagger:dagger-android-processor:$dagger2_version"
// compileOnly "org.glassfish:javax.annotation:3.1.1"
I hope you can help me, I'm trying to implement autovalue in my android project, but the code is not been generated.
I added in app/build.gradle:
provided 'com.google.auto.value:auto-value:1.5.3'
annotationProcessor 'com.google.auto.value:auto-value:1.5.3'
annotationProcessor 'com.ryanharter.auto.value:auto-value-gson:0.7.0'
compile 'com.ryanharter.auto.value:auto-value-gson-annotations:0.7.0'
In android studio 3.0 default settings in compiler > annotation processors I checked Enable annotation processing, and selected Obtain processors from project classpath.
I created AutoValueGsonFactory class like this:
import com.google.gson.TypeAdapterFactory;
import com.ryanharter.auto.value.gson.GsonTypeAdapterFactory;
#GsonTypeAdapterFactory
public abstract class AutoValueGsonFactory implements TypeAdapterFactory {
// Static factory method to access the package
// private generated implementation
public static TypeAdapterFactory create() {
return new AutoValueGson_AutoValueGsonFactory();
}
}
Then I click on Build > Rebuild Project
But is not working, throw this error:
Error:(16, 20) error: cannot find symbol class AutoValueGson_AutoValueGsonFactory
What I'm doing wrong or what I'm missing?
Create one model class and then rebuild the project.
The Error will be gone by now :)
Below is a sample model class created using ROBOPOJO plugin in android studio
import com.google.auto.value.AutoValue;
import com.google.gson.TypeAdapter;
import com.google.gson.annotations.SerializedName;
import com.google.gson.Gson;
import com.intellicar.finder.Data;
#AutoValue
public abstract class LoginData{
#SerializedName("msg")
public abstract String msg();
#SerializedName("data")
public abstract Data data();
#SerializedName("err")
public abstract Object err();
#SerializedName("status")
public abstract String status();
public static TypeAdapter<LoginData> typeAdapter(Gson gson) {
return new AutoValue_LoginData.GsonTypeAdapter(gson);
}
}
I started using dagger 2.2 and the module methods in the Component builder are deprecated.
This is my Application component :
#Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
void inject(Application application);
}
And the Application module:
#Module
public class ApplicationModule {
Application application;
public ApplicationModule(Application application) {
this.application = application;
}
#Provides
#Singleton
Application providesApplication() {
return application;
}
}
Here is the generated class:
#Generated(
value = "dagger.internal.codegen.ComponentProcessor",
comments = "https://google.github.io/dagger"
)
public final class DaggerApplicationComponent implements ApplicationComponent {
private DaggerApplicationComponent(Builder builder) {
assert builder != null;
}
public static Builder builder() {
return new Builder();
}
public static ApplicationComponent create() {
return builder().build();
}
#Override
public void inject(Application application) {
MembersInjectors.<Application>noOp().injectMembers(application);
}
public static final class Builder {
private Builder() {}
public ApplicationComponent build() {
return new DaggerApplicationComponent(this);
}
/**
* #deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://google.github.io/dagger/unused-modules.
*/
#Deprecated
public Builder applicationModule(ApplicationModule applicationModule) {
Preconditions.checkNotNull(applicationModule);
return this;
}
}
}
How do I initialize the component if not with the ComponentBuilder?
You should read the description of why it is deprecated. If you are using an IDE like IntelliJ or Android Studio you can just select the method and hit Control + Q on Windows to read the Javadoc including the deprecation notice.
The Javadoc reads:
#deprecated This module is declared, but an instance is not used in the component. This method is a no-op. For more, see https://google.github.io/dagger/unused-modules.
And from this link you can see:
When the Dagger processor generates components, it only requires instances of modules and component dependencies that are explicitly needed to supply requests for a binding.
If all of a module’s methods that are used in the component are static, Dagger does not need an instance of that module at all. Dagger can invoke the static methods directly without a module.
If a module provides no bindings for a Component, no instance of that module is necessary to construct the graph.
It is safe to say that you can just ignore the deprecation. It is intended to notify you of unused methods and modules. As soon as you actually require / use Application somewhere in your subgraph the module is going to be needed, and the deprecation warning will go away.
It show deprecated because you are not using Component and module in your application by
#Inject
SomeObjectFromModule mSomeObject
if you are not injecting dependencies in your applications there is no use of initialising your component so dagger look for at least one usage
once you add these lines in any classes you want to inject views and then clean build and rebuild the project and your deprecation will be solved
It showing error when my Module have no #Provides method or the object that provide by Dagger is not used in app.
Example to remove deprecated module
Module
#Module
public class SecondActivityModule {
#Provides
Book provideBookTest() {
return new Book();
}
}
Activity
public class SecondActivity extends AppCompatActivity {
#Inject
Book test;
...
}
OR in Component
#Component(modules = SecondModule.class)
public interface SecondComponent {
void inject(SecondActivity activity);
Book getBookTest();
}
I have the same problem with host and I just want everyone has deprecated issue on Generated component builder class should check two things to save time:
1/ Correct dagger syntax for module, component also check carefully where you inject.
2/ Must have injection object (inject annotation and its object) in place you want to inject or else the dagger compiler cannot see where to use your module so some method will be deprecated.Just inject at least one module's provides to your injection place and re-compile the code, you won't have that issue anymore :)
you will get module method deprecated if you declare void inject(AppCompactActivity activity); in component class. instead of you have to use tight coupling like following void inject(MainActivity activity);and rebuild your project you will see, there is no deprecate method in module class
The DaggerMock library, is used to override dagger modules with fake implementation. Lets take a look at one robolectric topic that is confusing me:
#RunWith(RobolectricGradleTestRunner.class)
#Config(constants = BuildConfig.class, sdk = 21)
public class MainActivityTest {
#Rule public final DaggerMockRule<MyComponent> mockitoRule = new DaggerMockRule<>(MyComponent.class, new MyModule())
.set(new DaggerMockRule.ComponentSetter<MyComponent>() {
#Override public void setComponent(MyComponent component) {
((App) RuntimeEnvironment.application).setComponent(component);
}
});
#Mock RestService restService;
#Mock MyPrinter myPrinter;
#Test
public void testCreateActivity() {
when(restService.doSomething()).thenReturn("abc");
Robolectric.setupActivity(MainActivity.class);
verify(myPrinter).print("ABC");
}
}
So i want to know, with this Rule what exactly is happening ? I can see that RestService was being provided by MyModule but is now being replaced with a mock. But in the examples i don't see a #Inject anywhere so i'm confused how the module was even used in the first place to provide any dependencies ?
I am the author of DaggerMock, thanks for trying it!
The implementation is a bit complicated, the rule create a dynamic subclass of the module (using mockito) and override the provides methods. The rule scans the test fields so it return a field when the module has a method that returns the same type.
The final result is very similar to Mockito InjectMocks annotation. You can take a look at the implementation on github, the core class that override the module is this: https://github.com/fabioCollini/DaggerMock/blob/master/lib/src/main/java/it/cosenonjaviste/daggermock/MockOverrider.java
I release this lib just a week ago, any feedback is welcome!