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) 并解决了问题。