10

我正在尝试使用新的架构组件,但我对 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;
    }
}

存储库

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

日志猫

... 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)
4

1 回答 1

4

正如 NPE 所建议的那样,该问题是由于ViewModelFactory您的 . MainActivity这本身很可能是由于ViewModelFactory没有正确注入,因此保持为空。正如 Orest 在评论中建议的那样,您需要确保MainActivity从您的AppModule:

主要活动:

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 类,如果没有 @Provides- 或 @Produces-annotated 方法就无法提供,看看该设置是否有帮助你出去。

于 2017-07-02T09:45:01.173 回答