Java 如何正确使用Dagger2和新的Android架构组件
我正在尝试使用新的体系结构组件,但我对dagger还是新手,我缺少一些东西 使用下面的代码,我得到一个NullPointerException,无法定位到何处。 此外,如果我还有其他需要修复或改进的地方,请提出建议 代码: 视图模型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;
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;
}
}