Room getItemById查询不适用于LiveData

时间:2018-07-19 18:09:32

标签: android android-room android-livedata

我使用LiveData和Room数据库设置了我的应用程序。 当我执行“ getAll”查询时,一切都会正常进行。 问题是当我想获取具有特定ID的度量值列表时,我的查询返回空值。我调试了它,看来LiveData可以正常工作,这就是为什么我怀疑Room部分不能正常工作的原因,尽管语法似乎正确。 我调试了数据库,所有数据都正确保存,只是没有显示在Ui上。

Dao片段:

public interface MeasureDao {

@Query("SELECT * FROM measure")
LiveData<List<Measure>> getAll();

@Query("SELECT * FROM measure where sheet_id=:sheetId")
 LiveData<List<Measure>> getMeasuresOfSheet(final long sheetId);

第二行返回空。

型号:

@Entity(tableName = "measure",
    foreignKeys = @ForeignKey(onDelete = CASCADE, entity = Sheet.class, parentColumns = "id", childColumns = "sheet_id"),
    indices = {@Index("id"), @Index(value = {"measure_number", "beats"}), @Index("sheet_id")})

公共类Measure实现可序列化,可比较的{

@Embedded
TimeSignature timeSignature;

@NonNull
@ColumnInfo(name = "sheet_id")
public long sheetId;

@NonNull
@PrimaryKey(autoGenerate = true)
int id;

@ColumnInfo(name = "measure_number")
public Integer measureNumber;


@ColumnInfo(name = "time_signature")

String timeSig;

boolean showTimeSig = true;

List<Beat> beats = new ArrayList<>();

public Measure() {
    this.getBeats();
}


public Measure(int number, List<Beat> beats, TimeSignature timeSignature, boolean showTimeSig, long sheetId) {
    this.beats = beats;
    this.measureNumber = number;
    this.timeSignature = timeSignature;
    this.showTimeSig = showTimeSig;
    this.sheetId = sheetId;


    int s = beats.size();
    int x = timeSignature.getNumerator();
    if (timeSignature.numerator == x) {
        s = x;
    }
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public long getSheetId() {
    return sheetId;
}

public void setSheetId(long sheetId) {
    this.sheetId = sheetId;
}


public List<Beat> getBeats() {
    return beats;
}

public int getNumber() {
    return measureNumber;
}

public void setNumber(int number) {
    this.measureNumber = number;
}

public void setBeats(List<Beat> beats) {
    this.beats = beats;
}

public void addBeat(Beat beat) {

    try {

        if (beats.size() <= timeSignature.getNumerator())
            beats.add(new Beat(" "));
    }
    catch (Exception e) {
        Log.v("BeatsException", "Too many beats.");

    }
}

public TimeSignature getTimeSignature() {
    return timeSignature;
}

public void setTimeSignature(int numerator, int denominator) {
    this.timeSignature = timeSignature;
}

public void removeBeat(int pos) {
    beats.remove(pos);
}

public boolean isShowTimeSig() {
    return showTimeSig;
}

public void setShowTimeSig(boolean showTimeSig) {
    this.showTimeSig = showTimeSig;
}

public void setTimeSignature(TimeSignature timeSignature) {
    this.timeSignature = timeSignature;
}

public String getTimeSig() {
    return timeSig;
}

public void setTimeSig(String timeSig) {
    this.timeSig = timeSig;
}

@Override
public int compareTo(@NonNull Measure o) {
    int cmp = this.measureNumber.compareTo(o.measureNumber);
    if (cmp != 0) {
        return cmp;
    }
    boolean bool = this.getBeats().equals(o.getBeats());
    if (bool) {
        return 0;
    } else {
        return 1;
    }
}

}

存储库:

public class MeasureRepository {


private static MeasureRepository sInstance;
private final AppDataBase mDatabase;
private MediatorLiveData<List<Measure>> mObservableMeasures;
private MediatorLiveData<List<Measure>> mObservableMeasuresBySheet;
private MutableLiveData<List<Measure>> measuresBySheetMutable;

public AppExecutors appExecutors = new AppExecutors();

long mSheetId;


//private constructor
private MeasureRepository(final AppDataBase database, long sheetId) {

    mDatabase = database;

    mSheetId = sheetId;


    mObservableMeasures = new MediatorLiveData<>();
    mObservableMeasuresBySheet = new MediatorLiveData<>();

    mObservableMeasuresBySheet.addSource(mDatabase.measureDao().getMeasuresOfSheet(sheetId), new Observer<List<Measure>>() {
        @Override
        public void onChanged(@Nullable List<Measure> measuresBySheet) {
            if (mDatabase.getDatabaseCreated().getValue() != null) {
                appExecutors.diskIO().execute(() ->
                        mObservableMeasuresBySheet.postValue(measuresBySheet));
            }
        }
    });


public static MeasureRepository getInstance(final AppDataBase database, long sheetId) {
    if (sInstance == null) {
        synchronized (MeasureRepository.class) {
            if (sInstance == null) {
                sInstance = new MeasureRepository(database, sheetId);
            }
        }
    }
    return sInstance;
}

/*****Room Measures DAO*****/

public void addNewMeasure(Measure measure, AtomicBoolean lock) {

    appExecutors.diskIO().execute(new Runnable() {
        @Override
        public void run() {

            if (!lock.get()) {
                lock.set(true);
                mDatabase.measureDao().newMeasure(measure);
            }
            lock.set(false);
        }


    });

    Log.d("ADD_MEASURE", "Added empty measure to database");

}


public void saveMeasures(List<Measure> measures) {
    appExecutors.diskIO().execute(() ->
            mDatabase.measureDao().insertAll(measures));
}

public LiveData<List<Measure>> getAllMeasures() {

    return mObservableMeasures;
}

public LiveData<List<Measure>> getMeasuresBySheet() {
    return mObservableMeasuresBySheet;
}

最后一种方法是无效的方法。

ViewModel:

public class MeasureListViewModel extends AndroidViewModel {

// MediatorLiveData can observe other LiveData objects and react on their emissions.
private final MediatorLiveData<List<Measure>> mObservableMeasures;
private final MediatorLiveData<List<Measure>> mObservableMeasuresBySheet;

public MeasureListViewModel(Application application) {
    super(application);

    mObservableMeasures = new MediatorLiveData<>();
    mObservableMeasuresBySheet = new MediatorLiveData<>();


    // set by default null, until we get data from the database.
    mObservableMeasures.setValue(null);
    mObservableMeasuresBySheet.setValue(null);


    LiveData<List<Measure>> measures = ((BasicApp) application).getMeasureRepository()
            .getAllMeasures();

    // observe the changes of the measures from the database and forward them
    mObservableMeasures.addSource(measures, mObservableMeasures::setValue);

    LiveData<List<Measure>> measuresBySheet = ((BasicApp) application).getMeasureRepository()
            .getMeasuresBySheet();

    mObservableMeasuresBySheet.addSource(measuresBySheet, mObservableMeasuresBySheet::setValue);
}


/**
 * Expose the LiveData Products query so the UI can observe it.
 */
public LiveData<List<Measure>> getMeasures() {
    return mObservableMeasures;
}

public LiveData<List<Measure>> getMeasuresBySheet(Application application) {
    return ((BasicApp) application).getMeasureRepository().getMeasuresBySheet();
}

主要活动

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initSharedPrefs();

    ((BasicApp) getApplication()).setSheetId(getIntent().getExtras().getLong(SHEET_ID_INTENT_KEY));

    final MeasureListViewModel measureListViewModel = ViewModelProviders.of(this).get(MeasureListViewModel.class);
    this.viewModel = measureListViewModel;

    final SheetListViewModel sheetListViewModel = ViewModelProviders.of(this).get(SheetListViewModel.class);

    initializeViews(measureListViewModel);

    observeViewModel(measureListViewModel, sheetListViewModel);


    setupActionbar();

}



    counterView = getLayoutInflater().inflate(R.layout.counter_view, null);
    actionBar.setCustomView(counterView);



    TextView titleTV = findViewById(R.id.sheet_title_tv);
    titleTV.setText(getIntent().getExtras().getString(SHEET_TITLE_INTENT_KEY));
    TextView authorTV = findViewById(R.id.sheet_author_tv);
    authorTV.setText("by " + getIntent().getExtras().getString(SHEET_AUTHOR_INTENT_KEY));
    appBarLayout = findViewById(R.id.main_appbar);
}



    // Update the list when the data changes
    measureListViewModel.getMeasuresBySheet(getApplication()).observe(this, new Observer<List<Measure>>() {
        @Override
        public void onChanged(@Nullable List<Measure> measures) {
            if (measures != null && measures.size() != 0) {


                if (measuresAdapter == null) {

                    measuresAdapter = new MeasuresAdapter(getApplicationContext(), beatClickCallback);
                    recyclerView.setAdapter(measuresAdapter);
                }
                measuresAdapter.setMeasuresList(measures, getApplicationContext());


            }
        }
    });

sheetID传递到Application类,然后通过构造函数从那里传递到存储库。我检查了ID是否不为null并按时获取。

我们将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:0)

问题已解决-问题出在MeasureRepository.getInstance()中。我已经对其进行了修改,以检查其sheetId是否与参数中的不同。如果是这样,请返回具有更新的sheetId的新实例:

public void dynamicExpectedConditions(methodName){

Class<ExpectedConditions> expectedConditions = ExpectedConditions.class
Constructor <ExpectedConditions> constructor=expectedConditions.getConstructor(null);
ExpectedConditions econditions = constructor.newInstance(null);
Method method = ExpectedConditions.class.getMethod("methodName");
eConditions = (ExpectedConditions) method.invoke(eConditions, null);

}

现在可以使用了:)

更新:按照朋友的建议,我没有重新实例化MeasureRepository类,而是使用一个公共方法来更新它对sheetId的观察,我从MeasureListViewModel调用了它。