无法观察空数据 - 带有 Livedata 的 MVVM

Cannot observe null data - MVVM with Livedata

我使用 MVVM 模式和 LiveData 创建了简单的应用程序来观察数据。我显示的列表显示在片段中。对我来说,一切似乎都很好,因为我将我的代码与其他有效的示例进行了比较,但没有发现任何错误。

当 activity 启动时,我交换片段并在 onActivityCreatedmViewModel.getAllShops().observe(this, new Observer<List<Shop>>() { //<--error 中出现以下错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.lifecycle.LiveData.observe(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Observer)' on a null object reference

我的架构是:
- 实体 - Shop.class
- 道 - ShopDao.class
- 资料库 - ShopRepository.class
- ViewModel - ShopListViewModel
- 在 RecyclerView 中显示数据的片段 - ShopList.java

Shop.class:

@Entity(tableName = "shops")
public class Shop {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id")
    public int id;

    @ColumnInfo(name = "shop_name")
    public String shopName;

    @ColumnInfo(name = "shop_description")
    public String shopDescription;

    @ColumnInfo(name = "radius")
    public int radius;

    @ColumnInfo(name = "latitude")
    public String latitude;

    @ColumnInfo(name = "longitude")
    public String longitude;

    @ColumnInfo(name = "isFavourite")
    public int isFavouriteShop;

    public int getId() {
        return id;
    }

    public String getShopName() {
        return shopName;
    }

    public String getShopDescription() {
        return shopDescription;
    }

    public int getRadius() {
        return radius;
    }

    public String getLatitude() {
        return latitude;
    }

    public String getLongitude() {
        return longitude;
    }

    public int getIsFavouriteShop() {
        return isFavouriteShop;
    }



    @Ignore
    public Shop(String shopName, String shopDescription, int radius, String latitude, String longitude, int isFavouriteShop) {
        this.shopName = shopName;
        this.shopDescription = shopDescription;
        this.radius = radius;
        this.latitude = latitude;
        this.longitude = longitude;
        this.isFavouriteShop = isFavouriteShop;
    }

    public Shop(int id, String shopName, String shopDescription, int radius, String latitude, String longitude, int isFavouriteShop) {
        this.id = id;
        this.shopName = shopName;
        this.shopDescription = shopDescription;
        this.radius = radius;
        this.latitude = latitude;
        this.longitude = longitude;
        this.isFavouriteShop = isFavouriteShop;
    }
}

ShopDao.class:

@Dao
public interface ShopDao {

    @Query("SELECT * FROM shops")
    LiveData<List<Shop>> getAllShops();
}

存储库:

public class ShopRepository {

    private ShopDao dao;
    private LiveData<List<Shop>> mAllShops;

    public ShopRepository(Application application){
        dao = ShopDatabase.getInstance(application).dao();
        mAllShops = dao.getAllShops();
    }

    public LiveData<List<Shop>> getAllShops() {
        return mAllShops;
    }

视图模型:

public class ShopListViewModel extends ViewModel {


    private LiveData<List<Shop>> mAllShops;
    private ShopRepository mRepository;

    public ShopListViewModel(Application application) {
        mRepository = new ShopRepository(application);
        mAllShops = mRepository.getAllShops();

    }

    public ShopListViewModel() {
    }

    public LiveData<List<Shop>> getAllShops() {
        return mAllShops;
    }
}

onActivityCreated 的片段调用:

@Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mViewModel = ViewModelProviders.of(this).get(ShopListViewModel.class);
        mViewModel.getAllShops().observe(this, new Observer<List<Shop>>() { //<--error
            @Override
            public void onChanged(List<Shop> shops) {
                adapter.setList(shops);
            }
        });
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        recyclerView.setAdapter(adapter);
    }

加上数据库:

@Database(entities = {Shop.class}, version = 1, exportSchema = false)
public abstract class ShopDatabase extends RoomDatabase {

    public abstract ShopDao dao();

    private static volatile ShopDatabase INSTANCE;

    public static ShopDatabase getInstance(final Context context){
        if (INSTANCE == null){
            synchronized (ShopDatabase.class){
                if (INSTANCE == null){
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            ShopDatabase.class,
                            "shop_database.db")
                            .build();
                }
            }
        }
        return INSTANCE;
    }

}

我的 gradle 依赖项:

    implementation 'androidx.room:room-runtime:2.1.0-alpha03'
    annotationProcessor 'androidx.room:room-compiler:2.1.0-alpha03'

    // ViewModel and LiveData
    implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0-alpha01'
    annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.1.0-alpha01'

我的项目迁移到 Android X 所以我使用了那些。

我可以向数据库添加任何问题的项目,它们已保存并可用。

你们有谁能看到我做的任何赌注吗?
提前致谢!

mAllShops 变量在接受类型 Application 参数的构造函数中初始化。但是那个构造函数永远不会被调用。当您在 Fragment 中获取 ViewModel 时,它默认调用无参数构造函数。要让它调用您的参数化构造函数,您需要创建一个 ViewModelProvider.Factory.

尝试阅读 this

的 "ViewModel with non-default constructor" 部分