How to use Dagger2 with new Android architecture components

I am trying to use new architecture components, but I am also new to the dagger, and I lack material.

With the code below, I get a NullPointerException, cannot find where. Also, if there is anything else that I need to fix or improve, please suggest.

CODE: ViewModel

public class PostsVM extends ViewModel { private LiveData<StoryPost> post; private Repository repository; @Inject public PostsVM(Repository repository) { this.repository = repository; } public void init() { if (this.post != null) { return; } post = repository.getPosts(); } public LiveData<StoryPost> getPost() { return post; } } 

Repository

 @Singleton public class Repository { private final MutableLiveData<StoryPost> data = new MutableLiveData<>(); public LiveData<StoryPost> getPosts() { // new GetUser(post.getUid()) { @Override public void onSuccess(@NonNull User user) { // this is where I setValue// data.setValue(post); } @Override public void onError() { } @Override public void userNotFound() { } }; return data; } } 

Singleton factory

 @Singleton public class ViewModelFactory implements ViewModelProvider.Factory { private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators; @Inject public ViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) { this.creators = creators; } @SuppressWarnings("unchecked") @Override public <T extends ViewModel> T create(Class<T> modelClass) { Provider<? extends ViewModel> creator = creators.get(modelClass); if (creator == null) { for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) { if (modelClass.isAssignableFrom(entry.getKey())) { creator = entry.getValue(); break; } } } if (creator == null) { throw new IllegalArgumentException("unknown model class " + modelClass); } try { return (T) creator.get(); } catch (Exception e) { throw new RuntimeException(e); } } 

}

DAO

 @Dao public interface PostDao { @Query("SELECT * FROM posts ORDER by time DESC") LiveData<List<StoryPost>> getAll(); @Query("SELECT * FROM posts WHERE id = :id") LiveData<List<StoryPost>> getPost(String id); @Insert(onConflict = OnConflictStrategy.REPLACE) @NonNull void insert(StoryPost... posts); @Delete void delete(StoryPost post); @Update void update(StoryPost post); } 

Then in MainActivity:

 @Inject public ViewModelFactory factory; //... //*onCreate* PostsVM model = ViewModelProviders.of(this, factory).get(PostsVM.class); model.init(); final Observer<StoryPost> observer = post -> storyAdapter.insert(post); model.getPost().observe(this, observer); 

Logcat :

 ... java.lang.NullPointerException: Attempt to invoke interface method 'android.arch.lifecycle.ViewModel android.arch.lifecycle.ViewModelProvider $Factory.create(java.lang.Class)' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2479) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2539) at android.app.ActivityThread.access$900(ActivityThread.java:168) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1378) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:150) at android.app.ActivityThread.main(ActivityThread.java:5665) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:799) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:689) Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'android.arch.lifecycle.ViewModel android.arch.lifecycle.ViewModelProvider$Factory.create(java.lang.Class)' on a null object reference at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:128) at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:96) at com.aollay.smartpaper.MainActivity.bindDatabase(MainActivity.java:238) at com.aollay.smartpaper.MainActivity.populateNews(MainActivity.java:233) at com.aollay.smartpaper.MainActivity.config(MainActivity.java:159) at com.aollay.smartpaper.MainActivity.onCreate(MainActivity.java:74) at android.app.Activity.performCreate(Activity.java:6372) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2432) 
+8
java android dagger-2 architecture-components model-view
source share
1 answer

The problem is because the ViewModelFactory instance is null inside your MainActivity , as NPE suggests. This in itself is most likely due to the fact that the ViewModelFactory not entered properly, thus remaining zero. As Orestes points out inside the comments, you need to make sure that MainActivity correctly entered from your AppModule :

MainActivity:

 public class MainActivity extends AppCompatActivity implements HasSupportFragmentInjector { @Override protected void onCreate(Bundle savedInstanceState) { AndroidInjection.inject(activity); super.onCreate(savedInstanceState); } // if your Activity also has Fragments which need to be injected @Inject DispatchingAndroidInjector<Fragment> androidInjector; @Override public DispatchingAndroidInjector<Fragment> supportFragmentInjector() { return androidInjector; } } 

You can take a look at most of the DI classes that are used in the related question that I posted earlier in AndroidInjector <android.app.Activity> cannot be provided without the @ Provides- or @ Produces-annotated method and see if this setting helps.

+1
source share

All Articles