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

Java 如何正确使用Dagger2和新的Android架构组件,java,android,dagger-2,model-view,android-architecture-components,Java,Android,Dagger 2,Model View,Android Architecture Components,我正在尝试使用新的体系结构组件,但我对dagger还是新手,我缺少一些东西 使用下面的代码,我得到一个NullPointerException,无法定位到何处。 此外,如果我还有其他需要修复或改进的地方,请提出建议 代码: 视图模型 public class PostsVM extends ViewModel { private LiveData<StoryPost> post; private Repository repository;

我正在尝试使用新的体系结构组件,但我对dagger还是新手,我缺少一些东西

使用下面的代码,我得到一个NullPointerException,无法定位到何处。 此外,如果我还有其他需要修复或改进的地方,请提出建议

代码: 视图模型

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

正如NPE所建议的,该问题是由
ViewModelFactory
实例在
MainActivity
中为空引起的。这本身很可能是由于
ViewModelFactory
没有正确注入,因此保持为空。正如Orest在注释中所建议的,您需要确保从
AppModule
正确注入
MainActivity

main活动:

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;
    }
}
public类MainActivity扩展AppCompatActivity实现HasSupportFragmentInjector
{
@凌驾
创建时受保护的void(Bundle savedInstanceState)
{
雄激素注射:注射(活性);
super.onCreate(savedInstanceState);
}
//如果您的活动也有需要注入的片段
@注入
调度安卓注射液安卓注射液;
@凌驾
公开分派androidInjector支持FragmentInjector()
{
回程雄激素注射;
}
}

您可以查看我之前在上发布的一个相关问题中使用的大多数DI类,看看该设置是否对您有所帮助。

您是否调用了InjectorClass。在创建活动时注入(此)类?@OrestSavchak,不,我没有,什么是
InjectorClass
我的意思是在哪里创建ViewModelFactory实例?我以为这样就可以了<代码>@Inject public ViewModelProvider.Factory,我错了吗?您需要在onCreate方法开始时调用AndroidInjection.Injection(this)。但同样的,您必须定义模块类,并提供规则和组件接口以及inject(MainActivity)方法。
@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
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);
}
@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);
... 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)
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;
    }
}