Injecting dataSource class to presenter gives null - android

I'm trying to inject DataSource class to Presenter using Dagger 2, but dataSource is null.
The code is below :
public class MainPresenter implements MainMVP.Presenter {
public static final String TAG = "MAIN-PRESENTER";
#NonNull
private MainMVP.View mainView;
#Inject
DataSource dataSource;
public MainPresenter(#NonNull MainMVP.View mainView) {
this.mainView = mainView;
Log.i(TAG, "MainPresenter init");
DaggerDataComponent.builder()
.dataModule(new DataModule())
.build();
}
#Override
public void onButtonClick() {
if (dataSource != null) {
mainView.showData(dataSource.getReleaseString());
}
}
}
If I remove the condition that checks for null in dataSource I'm getting a NullPointerException. Anyone can help with that? Isn't the constructor the right place to build the DataComponent ?

You're building your component but you don't seem to be actually using it.
DataCompontent component = DaggerDataComponent.builder()
.dataModule(new DataModule())
.build();
component.inject(this);
and add
void inject(MainPresenter presenter);
to your DataComponent interface.
As for your question about if that is the right place to build your component: we can't really answer that. That strongly depends on your code architecture.
Here's a nice example of MVP + dagger2 architecture. Maybe try following that.

Related

MVVM - Having a hard time understanding how to create the Domain layer in Clean Architecture

I'm trying to learn MVVM to make my app's architecture more clean. But I'm having a hard time grasping how to create a "Domain" layer for my app.
Currently this is how the structure of my project is looking:
My View is the activity. My ViewModel has a public method that the activity can call. Once the method in the ViewModel is called, it calls a method in my Repository class which performs a network call, which then returns the data back to the ViewModel. I then update the LiveData in the ViewModel so the Activity's UI is updated.
This is where I'm confused on how to add a Domain layer to the structure. I've read a lot of Stackoverflow answers and blogs about the Domain layer and they mostly all tell you to remove all the business logic from the ViewModel and make a pure Java/Kotlin class.
So instead of
View --> ViewModel --> Repository
I would be communicating from the ViewModel to the Domain class and the Domain class would communicate with the Repository?
View --> ViewModel --> Domain --> Repository
I'm using RxJava to make the call from my ViewModel to the Repository class.
#HiltViewModel
public class PostViewModel extends ViewModel {
private static final String TAG = "PostViewModel";
private final List<Post> listPosts = new ArrayList<>();
private final MutableLiveData<List<Post>> getPostsLiveData = new MutableLiveData<>();
private final MutableLiveData<Boolean> centerProgressLiveData = new MutableLiveData<>();
private final MainRepository repository;
#Inject
public PostViewModel(MainRepository repository) {
this.repository = repository;
getSubredditPosts();
}
public void getSubredditPosts() {
repository.getSubredditPosts()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Response>() {
#Override
public void onSubscribe(#NonNull Disposable d) {
centerProgressLiveData.setValue(true);
}
#Override
public void onNext(#NonNull Response response) {
Log.d(TAG, "onNext: Query called");
centerProgressLiveData.setValue(false);
listPosts.clear();
listPosts.addAll(response.getData().getChildren());
getPostsLiveData.setValue(listPosts);
}
#Override
public void onError(#NonNull Throwable e) {
Log.e(TAG, "onError: getPosts", e);
centerProgressLiveData.setValue(false);
}
#Override
public void onComplete() {
}
});
}
public class MainRepository {
private final MainService service;
#Inject
public MainRepository(MainService service) {
this.service = service;
}
public Observable<Response> getSubredditPosts() {
return service.getSubredditPosts();
}
}
Could someone please give me an example of how I could do it? I'm quite lost here
I had a hard time while trying to figure out the domain layer.
The most common example of it is the use case.
Your viewmodel won't communicate directly to the repository. As you said, you need viewmodel 》domain 》repository.
You may think of a usecase as a abstraction for every repository method.
Let's say you have a Movies Repository where you call a method for a movie list, another method for movie details and a third method for related movies.
You'll have a usecase for every single method.
What's the purpose of it?
Let's say you have a DetailActivity that communicate with a Detail Viewmodel. Your viewmodel doesn't need to know all the repository (what's the purpose of calling a movie list method on you Detail screen?). So, all your DetailViewModel will know is "Detail Usecase " (that calls the Detail method in repository).
Google has updated the architecture documentation few hours ago, take a look!
https://android-developers.googleblog.com/2021/12/rebuilding-our-guide-to-app-architecture.html?m=1&s=09
PS: Usecase is not a special android class, you do not need to inherent any behavior (as fragment, activity, viewmodel...) it's a normal class that will receive the repository as parameter.
You'll have something like:
Viewmodel:
function createPost(post Post){
createUseCase.create(post)
}
UseCase
function createPost(post Post): Response {
return repository.create(post)
}
I spent quite a bit of time trying to learn how to add a domain layer using RxJava by reading a lot of blogs and Stackoverflow answers, but all of them were missing the conversion of the response from the api call to what you'd like to display on screen (For example if the back end returns a username dave123 and you'd like to display by dave123).
I finally figured it out and the secret sauce was to use a RxJava .map() operator inside the UseCase class. I also decided to keep the RxJava call inside my ViewModel.
So in my Repository class I have a method that calls the Api and returns a type of Single<Response>. This is the raw json data the Api returns.
public class MainRepository {
private final MainService service;
private final PostDao postDao;
#Inject
public MainRepository(MainService service, PostDao postDao) {
this.service = service;
this.postDao = postDao;
}
public Single<Response> getResponse() {
return service.getSubredditPosts();
}
}
Inside my GetPostsUseCase class, I'm call the getResponse() method from the MainRepository and altering the Response by performing business logic on it (the stuff I want to display on the UI. In this case I add the String "by " to the username)
And the secret or the part I had alot of trouble understanding/figuring out how to do was converting the Type inside the Single<>. I used the .map() operator to change the return type and filter the Response to a List<Post>
public class GetPostsUseCase {
private final MainRepository mainRepository;
#Inject
public GetPostsUseCase(MainRepository mainRepository) {
this.mainRepository = mainRepository;
}
public Single<List<Post>> getSubredditPosts(){
return mainRepository.getResponse().map(response ->
getPostsFromResponse(response.getData().getChildren())
);
}
private List<Post> getPostsFromResponse(List<Child> listChildren) {
List<Post> listPosts = new ArrayList<>();
for (Child child : listChildren) {
Post post = child.getPost();
post.setCreatedBy("by " + post.getUsername());
listPosts.add(post);
}
return listPosts;
}
}
And this is how my ViewModel looks like
public class PostViewModel extends ViewModel {
private static final String TAG = "PostViewModel";
private final List<Post> listPosts = new ArrayList<>();
private final MutableLiveData<List<Post>> getPostsLiveData = new MutableLiveData<>();
private final MutableLiveData<Boolean> centerProgressLiveData = new MutableLiveData<>();
private final GetPostsUseCase getPostsUseCase;
#Inject
public PostViewModel(GetPostsUseCase getPostsUseCase) {
this.getPostsUseCase = getPostsUseCase;
getSubredditPosts();
}
public void getSubredditPosts() {
getPostsUseCase.getSubredditPosts()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SingleObserver<List<Post>>() {
#Override
public void onSubscribe(#NonNull Disposable d) {
centerProgressLiveData.setValue(true);
}
#Override
public void onSuccess(#NonNull List<Post> list) {
Log.d(TAG, "onNext: Query called");
centerProgressLiveData.setValue(false);
listPosts.clear();
listPosts.addAll(list);
getPostsLiveData.setValue(listPosts);
}
#Override
public void onError(#NonNull Throwable e) {
centerProgressLiveData.setValue(false);
}
});
}
I couldn't find any blogposts or answers that had an example like this. Hopefully this helps anyone out there who is struggling to learn how to implement clean architecture with MVVM, Hilt, RXJava and a Domain layer.
If I did do something incorrectly or not considered clean architecture please let me know.

Actual invocation has different arguments Unit Presenter

I create a unit test for my Presenter. My Presenter implements Listener callback if successfully load data from API (use Interactor):
PresenterTest.java
public class MainContactPresenterTest {
#Mock LoadContactInteractor loadContactInteractor;
#Mock ApiService apiService;
#Mock LoadContactView loadContactView;
#Mock ContactRepository contactRepository;
#Mock LoadContactInteractor.OnLoadDataFinishedListener listener;
#InjectMocks MainContactPresenterImpl presenter;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void getContactLists() {
// given
// when
presenter.fetchRemoteContacts();
// then
Mockito.verify(loadContactInteractor).onLoadData(listener);
}
}
Here is my Presenter:
public class MainContactPresenterImpl implements MainContactPresenter,
LoadContactInteractor.OnLoadDataFinishedListener {
private LoadContactView loadContactView;
private LoadContactInteractor loadContactInteractor;
private ContactRepository contactRepository;
#Inject
public MainContactPresenterImpl(LoadContactInteractor loadContactInteractor,
#NonNull LoadContactView loadContactView,
ContactRepository contactRepository) {
this.loadContactView = loadContactView;
this.loadContactInteractor = loadContactInteractor;
this.contactRepository = contactRepository;
}
#Override
public void onSuccessLoad(List<Contact> contacts) {
loadContactView.saveDataToLocalStorage(contacts);
}
#Override
public void onErrorLoad() {
loadContactView.dismissProgress();
loadContactView.showErrorMessage();
}
#Override
public void preCheckCacheData() {
if (contactRepository.getContactCount() == 0) {
// Load contacts from Server
fetchRemoteContacts();
} else {
fetchLocalContacts();
}
}
#Override
public void fetchRemoteContacts() {
loadContactView.showProgress();
loadContactInteractor.onLoadData(this);
}
}
But when I ran test, I got the mocking parameter in verify not match.
I got my presenter that have to be an argument. Not the listener.
Argument(s) are different! Wanted:
loadContactInteractor.onLoadData(
listener
);
Actual invocation has different arguments:
loadContactInteractor.onLoadData(
fanjavaid.gojek.com.contacts.presenter.MainContactPresenterImpl#1757cd72
);
How to handle that? Thank you
You are creating a mock...
#Mock LoadContactInteractor.OnLoadDataFinishedListener listener;
...and then you don't use it ever again and act suprised when verify tells you, that it wasn't actually used. Why? Of course it wasn't used, since you never use it anywhere, so how should your classes know to use that mock object?
Your MainContactPresenterImpl does not use an OnLoadDataFinishedListener as an external dependency (then your could perhaps inject it via #InjectMocks), it is itself such a listener and thus mocking another listener makes no sense here.
In other words, MainContactPresenterImpl has no OnLoadDataFinishedListener field, so Mockito is of course not capable of injecting something in this non-existing field. For something like this to work, you would need to add such a field and then use the content of that field when calling your onLoadData method.
The only invocation of your method is here...
loadContactInteractor.onLoadData(this);
And what is this in that context? It's the MainContactPresenterImpl object that contains the method, in other words, your presenter.
So, what will work is...
Mockito.verify(loadContactInteractor).onLoadData(presenter);

android retrofit2, dagger2 unit test

I learn how to test the presenter layer of MVP architecture in android, my presenter using retrofit 2 and in my activity I used dagger 2 as dependency injection to my presenter, this is my Dagger and presenter injection looks like:
#Inject
AddScreenPresenter addScreenPresenter;
This is the Dagger builder :
DaggerAddScreenComponent.builder()
.netComponent(((App) getApplicationContext()).getNetComponent())
.addScreenModule(new AddScreenModule(this, new ContactDatabaseHelper(this)))
.build().inject(this);
and this is my presenter constructor :
#Inject
public AddScreenPresenter(Retrofit retrofit, AddScreenContact.View view, ContactDatabaseHelper contactDatabaseHelper)
{
this.retrofit = retrofit;
this.view = view;
this.contactDatabaseHelper = contactDatabaseHelper;
}
I have write the unit test class and mock the Retrofit class, but when I run it, the error appears :
Mockito cannot mock/spy following:
- final classes
- anonymous classes
- primitive types
This is the test class :
#RunWith(MockitoJUnitRunner.class)
public class AddScreenPresenterTest {
private AddScreenPresenter mAddPresenter;
#Mock
private Retrofit mRetrofit;
#Mock
private Context mContext;
#Mock
private AddScreenContact.View mView;
#Mock
private ContactDatabaseHelper mContactDatabaseHelper;
String firstName, phoneNumber;
Upload upload;
#Before
public void setup() {
mAddPresenter = new AddScreenPresenter(mRetrofit, mView, mContactDatabaseHelper);
firstName = "aFirstName";
phoneNumber = "998012341234";
Uri path = Uri.parse("android.resource://"+BuildConfig.APPLICATION_ID+"/" + R.drawable.missing);
upload = new Upload();
upload.title = firstName;
upload.description = "aDescription";
upload.albumId = "XXXXX";
upload.image = new File(path.getPath());
}
#Test
public void checkValidationTest() {
verify(mAddPresenter).checkValidation(firstName, phoneNumber);
}
#Test
public void uploadMultiPartTest() {
verify(mAddPresenter).uploadMultiPart(upload);
}
}
this is my module :
#Module
public class AddScreenModule {
private final AddScreenContact.View mView;
private final ContactDatabaseHelper mContactDatabaseHelper;
public AddScreenModule (AddScreenContact.View view, ContactDatabaseHelper contactDatabaseHelper)
{
this.mView = view;
this.mContactDatabaseHelper = contactDatabaseHelper;
}
#Provides
#CustomScope
AddScreenContact.View providesAddScreenContactView() {
return mView;
}
#Provides
#CustomScope
ContactDatabaseHelper providesContactDatabaseHelper() {
return mContactDatabaseHelper;
}
}
I know that Retrofit class is a final class, and now I stuck and don't know how to create the presenter object in my test class. Please help me, how to create the object of the presenter class with retrofit in the constructor. Feel free to ask if my question is not clear enough, and thank you very much for your help.
Personally I'd make the presenter not depend on the Retrofit class but rather on the services created by Retrofit - These are mockable.
It's hard to say from the code you posted which services your presenter actually uses, but for the sake of simplicity let's say it uses only one and let's say it's AddsService - This is an interface ready to work with Retrofit. Something like this for example
public interface AddsService {
#GET(...)
Call<List<Adds>> getAllAdds();
}
Now you can make your presenter depend on this rather than Retrofit
#Inject
public AddScreenPresenter(AddsService addsService,
AddScreenContact.View view,
ContactDatabaseHelper contactDatabaseHelper){
this.addsService = addsService;
this.view = view;
this.contactDatabaseHelper = contactDatabaseHelper;
}
You now need to provide this dependency. I'm guessing you have also a NetModule since you have a NetComponent, so I assume you can just do:
#Module
public class NetModule {
// Methods providing Retrofit
#Provides
#Singleton
public AddsService providesAddsService(Retrofit retrofit) {
return retrofit.create(AddsService.class);
}
}
Notice how the providesAddsService depends on retrofit? This should be already provided since your presenter is depending on it. You shouldn't need to change anything for that. Dagger is able to figure out how to provide Retrofit to the method providesAddsService.
Please notice also that I'm assuming you can provide these in a Singleton scope. I assume this because in your code you retrieve the component from the application, which should handle the singleton scope.
Now in your tests you can simply mock AddsService and test your presenter.
If your presenter depends on more services, I'd also pass them in the constructor and provide the implementations with Dagger.
As a bonus, let me also say that the retrofit instance and the retrofit services should only be created once (or at least as less times as possible). This is because they're usually expensive operations and you usually always query the same endpoints with different parameters.
EDIT
To answer some of the questions in the comments. First the easy one: How to create the presenter in the test classes? Like you I too try to get away from Dagger during tests, that's why I prefer constructor dependency injection just like you show you're using. So in my test class I'd have something very similar like you:
#RunWith(MockitoJUnitRunner.class)
public class AddScreenPresenterTest {
private AddScreenPresenter mAddPresenter;
#Mock
private AddsService addsService;
// ...
#Before
public void setUp() throws Exception {
mAddPresenter = new AddScreenPresenter(addsService,
mView, mContactDatabaseHelper);
// ...
}
}
So basically the only difference is that I would pass the mock to the service.
Now the second question: How to call the presenter constructor from the activity? Well you don't... that's the whole idea of dependency injection. You should use dagger to provide your presenter. I think this is already what you do and I guess this is what it's in your activity:
#Inject
AddScreenPresenter addScreenPresenter;
So all you need to do is have a provider method in your module that provides this and is able to inject it.
You can also make the component return the presenter provided by the module:
#Component(...)
public interface AddScreenComponent {
AddScreenPresenter getPresenter();
}
And then in your activity you'd do something like:
addScreenPresenter = component.getPresenter();
I don't really have any preference here. The key point is to understand that you should not build the objects yourself (unless inside #Modules). As a rule of thumb any time you see new being used that means you have a tight dependency on that object and you should extract it to be injected. So this is why you should avoid creating the presenter inside your activity. It will couple the presenter to the activity.

How can I replace Activity scoped dependencies with mocks using Dagger2

I have a scoped dependency in my Activity and I want to test that activity with some mocks. I have read about different approach that suggest to replace Application component with a test component during the test, but what I want is to replace the Activity component.
For example, I want to test the Activity against mock presenter in my MVP setup.
I believe that replacing component by calling setComponent() on Activity will not work, because Activity dependencies already injected via field injection, so during the test, real object will be used.
How can I resolve this issue? What about Dagger1? Is it has the same issue?
Injecting the Component
First, you create a static class to act as a factory for your Activity. Mine looks a little like this:
public class ActivityComponentFactory {
private static ActivityComponentFactory sInstance;
public static ActivityComponentFactory getInstance() {
if(sInstance == null) sInstance = new ActivityComponentFactory();
return sInstance;
}
#VisibleForTesting
public static void setInstance(ActivityComponentFactory instance) {
sInstance = instance;
}
private ActivityComponentFactory() {
// Singleton
}
public ActivityComponent createActivityComponent() {
return DaggerActivityComponent.create();
}
}
Then just do ActivityComponentFactory.getInstance().createActivityComponent().inject(this); inside your Activities.
For testing, you can replace the factory in your method, before the Activity is created.
Providing mocks
As #EpicPandaForce's answer makes clear, doing this the officially-supported way currently involves a lot of boilerplate and copy/pasted code. The Dagger 2 team need to provide a simpler way of partially overriding Modules.
Until they do though, here's my unnoficial way: Just extend the module.
Let's say you want to replace your ListViewPresenter with a mock. Say you have a PresenterModule which looks like this:
#Module #ActivityScope
public class PresenterModule {
#ActivityScope
public ListViewPresenter provideListViewPresenter() {
return new ListViewPresenter();
}
#ActivityScope
public SomeOtherPresenter provideSomeOtherPresenter() {
return new SomeOtherPresenter();
}
}
You can just do this in your test setup:
ActivityComponentFactory.setInstance(new ActivityComponentFactory() {
#Override
public ActivityComponent createActivityComponent() {
return DaggerActivityComponent.builder()
.presenterModule(new PresenterModule() {
#Override
public ListViewPresenter provideListViewPresenter() {
// Note you don't have to use Mockito, it's just what I use
return Mockito.mock(ListViewPresenter.class);
}
})
.build();
}
});
...and it just works!
Note that you don't have to include the #Provides annotation on the #Override method. In fact, if you do then the Dagger 2 code generation will fail.
This works because the Modules are just simple factories - the generated Component classes take care of caching instances of scoped instances. The #Scope annotations are used by the code generator, but are irrelevant at runtime.
You cannot override modules in Dagger2 [EDIT: you can, just don't specify the #Provides annotation on the mock), which would obviously be the proper solution: just use the builder().somethingModule(new MockSomethingModule()).build() and be done with it!
If you thought mocking is not possible, then I would have seen two possible solutions to this problem. You can either use the modules to contain a pluggable "provider" that can have its implementation changed (I don't favor this because it's just too verbose!)
public interface SomethingProvider {
Something something(Context context);
}
#Module
public class SomethingModule {
private SomethingProvider somethingProvider;
public SomethingModule(SomethingProvider somethingProvider) {
this.somethingProvider = somethingProvider;
}
#Provides
#Singleton
public Something something(Context context) {
return somethingProvider.something(context);
}
}
public class ProdSomethingProvider implements SomethingProvider {
public Something something(Context context) {
return new SomethingImpl(context);
}
}
public class TestSomethingProvider implements SomethingProvider {
public Something something(Context context) {
return new MockSomethingImpl(context);
}
}
SomethingComponent somethingComponent = DaggerSomethingComponent.builder()
.somethingModule(new SomethingModule(new ProdSomethingProvider()))
.build();
Or you can bring the provided classes and injection targets out into their own "metacomponent" interface, which your ApplicationComponent and your TestApplicationComponent extend from.
public interface MetaApplicationComponent {
Something something();
void inject(MainActivity mainActivity);
}
#Component(modules={SomethingModule.class})
#Singleton
public interface ApplicationComponent extends MetaApplicationComponent {
}
#Component(modules={MockSomethingModule.class})
#Singleton
public interface MockApplicationComponent extends MetaApplicationComponent {
}
The third solution is to just extend the modules like in #vaughandroid 's answer. Refer to that, that is the proper way of doing it.
As for activity scoped components... same thing as I mentioned here, it's just a different scope, really.
I've found the following post that solves the problem:
http://blog.sqisland.com/2015/04/dagger-2-espresso-2-mockito.html
You need first to allow to modify the component of the activity:
#Override public void onCreate() {
super.onCreate();
if (component == null) {
component = DaggerDemoApplication_ApplicationComponent
.builder()
.clockModule(new ClockModule())
.build();
}
}
public void setComponent(DemoComponent component) {
this.component = component;
}
public DemoComponent component() {
return component;
}
And modify it in the test case
#Before
public void setUp() {
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
DemoApplication app
= (DemoApplication) instrumentation.getTargetContext().getApplicationContext();
TestComponent component = DaggerMainActivityTest_TestComponent.builder()
.mockClockModule(new MockClockModule())
.build();
app.setComponent(component);
component.inject(this);
}

Map enums to Dagger injected classes (MapBinder equivalent)

I'm trying to inject a class at runtime using a factory to map enums to class types, But I'm running into an issue where it will throw an error when I try to inject it.
java.lang.IllegalArgumentException: No inject registered for members/com.example.android.push.DefaultPushHandlerStrategy. You must explicitly add it to the 'injects' option in one of your modules.
public class PushFactory {
private Map<PushType, Class<? extends PushHandlerStrategy>> classMap = new HashMap<PushType, Class<? extends PushHandlerStrategy>>();
#Inject
public PushFactory() {
classMap.put(PushType.DEFAULT, DefaultPushHandlerStrategy.class);
classMap.put(PushType.VIDEOS, VideosPushHandlerStrategy.class);
classMap.put(PushType.MESSAGE, MessagePushHandlerStrategy.class);
}
public PushHandlerStrategy getPushHandlerStategy(PushType type){
Class<? extends PushHandlerStrategy> klazz = classMap.get(type);
if(klazz == null){
klazz = DefaultPushHandlerStrategy.class;
}
ObjectGraph graph = App.getApplication().getObjectGraph();
return graph.get(klazz); // this line throws the exception
}
}
Basically, what I'm trying to achieve is instantiating a strategy based on some data that comes in a GCM push.
I DO have the following registered in a module.
#Module(
injects = {
PushFactory.class,
PushBroadcastReceiver.class
},
complete = false,
library = false
)
public class PushModule {
}
Any ideas what's wrong with my approach?
Edit:
I was able to achieve what I wanted by injecting providers, but it seems a bit cumbersome. Any way around this?
public class PushFactory {
private Map<PushType, Provider<? extends PushHandlerStrategy>> providerMap = new HashMap<PushType, Provider<? extends PushHandlerStrategy>>();
#Inject
public PushFactory(Provider<DefaultPushHandlerStrategy> d, Provider<VideosPushHandlerStrategy> v, Provider<MessagePushHandlerStrategy> m) {
providerMap.put(PushType.DEFAULT, d);
providerMap.put(PushType.VIDEOS, v);
providerMap.put(PushType.MESSAGE, m);
}
public PushHandlerStrategy getPushHandlerStrategy(PushType type){
Provider<? extends PushHandlerStrategy> provider = providerMap.get(type);
if(provider == null){
provider = providerMap.get(PushType.DEFAULT);
}
return provider.get();
}
}
Your original solution should be achievable but it seems like you're probably missing the injects definition of those class in your PushModule. Since you're creating those objects using objectGraph.get(class) directly and not through field or constructor injection, without adding those classes to the injects Dagger cannot know that those classes are needed and will not create any plumbing for them and therefore will fail at runtime.
#Module(
injects = {
PushFactory.class,
PushBroadcastReceiver.class,
DefaultPushHandlerStrategy.class,
VideosPushHandlerStrategy.class,
MessagePushHandlerStrategy.class
},
complete = false,
library = false
)
public class PushModule {
}

Categories

Resources