Обучаясь Android, я создал приложение для жителей кондо-комплекса, чтобы найти утилиты для своего подразделения. Есть 4 таблицы; таблица единиц измерения (строки <100), таблица газа (строки <100), таблица electri c (строки <100) и таблица водяных клапанов (строки <200). Пользователь изначально взаимодействует с двумя счетчиками; 1, чтобы выбрать их здание, а другой их блок. Эта информация используется для извлечения данных из таблицы единиц измерения для связи с другими таблицами. В верхней части счетчиков есть флажок, чтобы установить единицу измерения как «вашу», чтобы приложение открывалось с выбранным блоком в счетчиках. Обновление таблицы единиц измерения для «ваших» - единственное изменение, которое пользователь внесет в таблицы. Нет добавления строк или других обновлений, поэтому таблицы имеют статус c, так как новые утилиты будут добавляться ежедневно, не говоря уже о раз в год. </p>
Моя первая реализация была с действиями (без фрагментов) и SQLiteAssetHelper (расширяет SQLiteOpenHelper). Работало нормально, все очень последовательно. Настройка «твоя» работает отлично.
Вторая реализация для фрагментов, чтобы в полной мере использовать емкость дисплея планшета. Также перенесен в комнату на базе данных MVVM (LiveData) для передачи данных для базы данных и фрагментов. Не использовал allowMainThreadQueries, за исключением модульного теста.
Пример кода для сущности объекта ниже.
@Entity(tableName = "units")
public class Unit {
@NonNull
private int building; // Building number or street address that contains the unit
// 4561, 4571, 4575, 4581 or 4591
@NonNull
private int unit; // Unit number in the building, unit numbers repeat between buildings
@NonNull
private int stack; // Identify's the stack in which the unit resides. Last number of unit
// is that unit's stack (i.e. unit 203 belongs to stack 3)
@PrimaryKey(autoGenerate = false)
@ColumnInfo(name = "unit_id")
@NonNull
private int unitId; /* Combination of building and unit to make a unique identifier
(i.e. for building 4561 unit 203, unit ID is 4561203)
Note, building 4575 has a unit ID of 4575 since it has no units.
*/
@ColumnInfo(name = "stack_id")
@NonNull
private int stackId; // Combination of building and stack to make a unique identifier
// (i.e. for building 4561 unit 203, stack ID is 45613)
@NonNull
private int yours; /* Indicator of whether the unit is yours or the unit the user wants
the app to start up with already selected. Note that SQLite on
android does not have a boolean data type, so 0 is false, 1 is true.
*/
Пример кода для единицы DAO ниже.
@Dao
public interface UnitDao {
@Insert
void insert(Unit unit);
@Query("SELECT * FROM units WHERE unit_id = :requestedUnitId")
LiveData<Unit> getUnitByUnitId(int requestedUnitId);
@Query("SELECT * FROM units WHERE yours = 1 LIMIT 1")
LiveData<Unit> getYourUnit();
@Update
void setYourUnit(Unit unit);
@Query("UPDATE units SET yours = 0 WHERE yours = 1")
int clearYourUnit();
Пример кода для база данных ниже.
private static SeaporteHoaDatabase instance;
public abstract UnitDao unitDao();
public abstract WaterValveDao waterValveDao();
public abstract ElectricMeterDao electricMeterDao();
public abstract GasMeterDao gasMeterDao();
public static synchronized SeaporteHoaDatabase getInstance(Context context) {
/*
When no database instance exists,
1st, on first run, create the database from the assets directory
2nd, migrates when necessary
3rd, builds
*/
if (instance == null) {
instance = Room.databaseBuilder(context.getApplicationContext(),
SeaporteHoaDatabase.class, DB_NAME)
.createFromAsset("databases/" + DB_NAME)
.fallbackToDestructiveMigration()
.build();
}
return instance;
}
В модульном тестировании взаимодействие с таблицами работает хорошо, но я разрешаю запросы основного потока для LiveDataTestUtil, который также имеет встроенную задержку (wait).
In приложение, функциональные возможности для получения актуальной информации о полезности из таблиц газа, электричества c и водяных клапанов после выбора устройства работает нормально. Установка «твоего» в таблице единиц ведет себя странно. После установки «yours», закрытия приложения и перезапуска база данных не имеет его, и это первая проверка, которую делает приложение. Иногда возникает задержка, возможно, из-за фоновой обработки Room.
Пример кода для YourUnitFragment.
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
tvYourSelectedBuilding = getView().findViewById(R.id.tvYourSelectedBuilding);
tvYourSelectedUnit = getView().findViewById(R.id.tvYourSelectedUnit);
tvYourInfo = getView().findViewById(R.id.tvYourInfo);
tvYourPreviousHeader = getView().findViewById(R.id.tvYourPreviousHeader);
tvYourPreviousBuilding = getView().findViewById(R.id.tvYourPreviousBuilding);
tvYourPreviousUnit = getView().findViewById(R.id.tvYourPreviousUnit);
btnYes = getView().findViewById(R.id.btnYourUnitYes);
btnNo = getView().findViewById(R.id.btnYourUnitNo);
/*
Obtain the selected unit information
*/
unitSelectionViewModel = ViewModelProviders.of(getActivity()).get(UnitSelectionViewModel.class);
unitSelectionViewModel.getUnitSelected().observe(getViewLifecycleOwner(), new Observer<Unit>() {
@Override
public void onChanged(Unit unit) {
yourUnit = unit;
if (yourUnit != null) {
tvYourSelectedBuilding.setText(String.format(Locale.US, "%d", yourUnit.getBuilding()));
if (yourUnit.getBuilding() == 4575) {
tvYourSelectedUnit.setText(context.getString(R.string.unit_4575));
} else {
tvYourSelectedUnit.setText(String.format(Locale.US, "%d", yourUnit.getUnit()));
}
}
}
});
Поскольку таблицы маленькие, будут разрешены запросы основного потока и удаление Функциональность LiveData сделает приложение более последовательным? Похоже, так и должно быть. Или Room все еще делает что-то на заднем плане?