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

我正在尝试使用新的架构组件,但我还是匕首的新手,而且我很想丢东西。

使用下面的代码,我得到一个NullPointerException,找不到位置。 此外,如果我需要修复或改进其他内容,请建议。

代码: ViewModel

public class PostsVM extends ViewModel { private LiveData 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 getPost() { return post; } } 

知识库

 @Singleton public class Repository { private final MutableLiveData data = new MutableLiveData(); public LiveData 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工厂

 @Singleton public class ViewModelFactory implements ViewModelProvider.Factory { private final Map<Class, Provider> creators; @Inject public ViewModelFactory(Map<Class, Provider> creators) { this.creators = creators; } @SuppressWarnings("unchecked") @Override public  T create(Class modelClass) { Provider creator = creators.get(modelClass); if (creator == null) { for (Map.Entry<Class, Provider> 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> getAll(); @Query("SELECT * FROM posts WHERE id = :id") LiveData<List> 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 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) 

问题是由于ViewModelFactory实例为null,正如NPE所暗示的那样。 这本身很可能是因为没有正确注入ViewModelFactory ,因此保持为null。 正如Orest在评论中建议的那样,您需要确保从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 androidInjector; @Override public DispatchingAndroidInjector supportFragmentInjector() { return androidInjector; } } 

您可以查看我之前在AndroidInjector上发布的相关问题中使用的大多数DI类。 如果没有@ Provide-或@ Produces-annotated方法 , 则无法提供,并查看该设置是否有帮助你出去。