Android: 在 Fragment 中实例化 ViewModel 时出现 NullPointerException
Android: NullPointerException When Instantiating ViewModel in Fragment
当我尝试将 MyViewModel 实例化为 MyFragment 时出现 NullPointerException:
public class MyFragment extends Fragment {
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
myViewModel = new ViewModelProvider(this, new MyViewModelFactory(
requireActivity().getApplication(), 0))
.get(MyViewModel.class);
}
堆栈跟踪似乎指出了最后一行 .get(MyViewModel.class);而且我几天都无法让它工作。我使用 System.out.println() 对 getApplication() 进行了空检查并返回了一个值,所以我认为这不是问题所在。当我在 activity 上执行此操作时,我使用的这种方法工作得很好,但是当我尝试在 Fragment 上执行此操作时,出现了 NullPointerException。我应该更改什么才能使这项工作正常进行?
下面是我如何创建 ViewModelFactory class:
public class MyViewModelFactory implements ViewModelProvider.Factory {
private Application application;
private int intValue;
public MyViewModelFactory(Application paramApplication, int paramIntValue) {
application = paramApplication;
intValue = paramIntValue;
}
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if (modelClass == MyViewModel.class) {
return (T) new MyViewModel(application, intValue);
}
return null;
}
}
我的 ViewModel class:
public class MyViewModel extends AndroidViewModel {
private MyDataModelRepository myDataModelRepository;
private LiveData<List<MyDataModel>> liveDataListMyDataModel;
public MyViewModel(@NonNull Application application, int intValue) {
super(application);
myDataModelRepository= new myDataModelRepository(application);
if (intValue> 0) {
liveDataListMyDataModel= myDataModelRepository.getLiveDataListMyDataModelWhere(intValue);
} else {
liveDataListMyDataModel= myDataModelRepository.getLiveDataListMyDataModel();
}
}
}
尝试使用它来实例化 ViewModel
myViewModel = new ViewModelProvider(this, new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(MyViewModel.class);
希望这对您有所帮助。随时要求澄清...
我刚刚重新调查了我的堆栈跟踪:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'net.mypackage.DataModel.MyDataModel.MyDataModelDao net.mypackage.DataModel.MySystemDatabase.myDataModelDao()' on a null object reference
at net.mypackage.DataModel.MyDataModel.MyDataModelRepository.<init>(MyDataModelRepository.java:21)
at net.mypackage.ViewModel.MyViewModel.MyViewModel.<init>(MyViewModel.java:21)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:267)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at net.mypackage.View.MyFragment.onViewCreated(MyFragment.java:50)
并认为我的错误很可能来自我的存储库或数据库室 class,当我重新检查数据库时 class:
public static synchronized MyDatabase getInstance(Context context) {
if (myDatabase != null) {
myDatabase = Room.databaseBuilder(context.getApplicationContext(),
myDatabase.class,
"my_database")
.fallbackToDestructiveMigration()
.addCallback(roomCallback)
.build();
}
return myDatabase;
}
(myDatabase != null) 是我得到 NPE 的原因,代码中的指令是在构建数据库之前 myDatabase 必须不为 null,并且由于此实例在开始时为 null,它根本不会被建造,因此 NPE。
所以我将 (myDatabase != null) 更改为 (myDatabase == null) 并解决了问题。
当我尝试将 MyViewModel 实例化为 MyFragment 时出现 NullPointerException:
public class MyFragment extends Fragment {
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
myViewModel = new ViewModelProvider(this, new MyViewModelFactory(
requireActivity().getApplication(), 0))
.get(MyViewModel.class);
}
堆栈跟踪似乎指出了最后一行 .get(MyViewModel.class);而且我几天都无法让它工作。我使用 System.out.println() 对 getApplication() 进行了空检查并返回了一个值,所以我认为这不是问题所在。当我在 activity 上执行此操作时,我使用的这种方法工作得很好,但是当我尝试在 Fragment 上执行此操作时,出现了 NullPointerException。我应该更改什么才能使这项工作正常进行?
下面是我如何创建 ViewModelFactory class:
public class MyViewModelFactory implements ViewModelProvider.Factory {
private Application application;
private int intValue;
public MyViewModelFactory(Application paramApplication, int paramIntValue) {
application = paramApplication;
intValue = paramIntValue;
}
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if (modelClass == MyViewModel.class) {
return (T) new MyViewModel(application, intValue);
}
return null;
}
}
我的 ViewModel class:
public class MyViewModel extends AndroidViewModel {
private MyDataModelRepository myDataModelRepository;
private LiveData<List<MyDataModel>> liveDataListMyDataModel;
public MyViewModel(@NonNull Application application, int intValue) {
super(application);
myDataModelRepository= new myDataModelRepository(application);
if (intValue> 0) {
liveDataListMyDataModel= myDataModelRepository.getLiveDataListMyDataModelWhere(intValue);
} else {
liveDataListMyDataModel= myDataModelRepository.getLiveDataListMyDataModel();
}
}
}
尝试使用它来实例化 ViewModel
myViewModel = new ViewModelProvider(this, new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(MyViewModel.class);
希望这对您有所帮助。随时要求澄清...
我刚刚重新调查了我的堆栈跟踪:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'net.mypackage.DataModel.MyDataModel.MyDataModelDao net.mypackage.DataModel.MySystemDatabase.myDataModelDao()' on a null object reference
at net.mypackage.DataModel.MyDataModel.MyDataModelRepository.<init>(MyDataModelRepository.java:21)
at net.mypackage.ViewModel.MyViewModel.MyViewModel.<init>(MyViewModel.java:21)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:267)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at net.mypackage.View.MyFragment.onViewCreated(MyFragment.java:50)
并认为我的错误很可能来自我的存储库或数据库室 class,当我重新检查数据库时 class:
public static synchronized MyDatabase getInstance(Context context) {
if (myDatabase != null) {
myDatabase = Room.databaseBuilder(context.getApplicationContext(),
myDatabase.class,
"my_database")
.fallbackToDestructiveMigration()
.addCallback(roomCallback)
.build();
}
return myDatabase;
}
(myDatabase != null) 是我得到 NPE 的原因,代码中的指令是在构建数据库之前 myDatabase 必须不为 null,并且由于此实例在开始时为 null,它根本不会被建造,因此 NPE。
所以我将 (myDatabase != null) 更改为 (myDatabase == null) 并解决了问题。