如何正确使用Dagger2与新的Android架构组件

我正在尝试使用新的架构组件,但是我对于匕首还是一个新东西,而且我错过了一些东西。

用下面的代码,我得到一个NullPointerException,无法find的地方。 另外,如果还有其他问题需要解决或改进,请提出build议。

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; } } 

知识库

 @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 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); } 

然后在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) 

Solutions Collecting From Web of "如何正确使用Dagger2与新的Android架构组件"

这个问题是由于你的MainActivityViewModelFactory实例为空造成的,正如NPE所build议的那样。 这本身很可能是由于ViewModelFactory未被正确注入而导致的,因此保留为空。 正如Orest在注释中提出的build议,您需要确保MainActivityAppModule正确注入:

主要活动:

 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; } } 

你可以看看我在之前发布的AndroidInjector <android.app.Activity>中提到的相关问题中使用的大部分DI类, 如果没有@Proxy-或@ Produces-annotated方法 , 就不能提供它 ,看看这个设置是否有帮助你出去。