打开后,我的应用程序可以正常工作。它能够从原始文件夹中的文本文件中预填充数据库。当我打开显示练习列表的片段时,查询运行良好,并且可以看到整个列表。如果我按返回按钮完全退出应用程序,然后重新输入,没问题,列表将再次填充。问题是当我按“最近”按钮并单击“全部关闭”时。当我重新输入该应用程序时,所有练习的查询均不产生任何结果,并且该列表为空。我搜寻了高低,什么也没找到。希望所附的代码足以诊断问题。 AppDatabase类基于Google Architecture BasicSample应用。
@Database(entities = {BodySectionEntity.class, CardioEntity.class, ExerciseEntity.class, GoalEntity.class, SetRecordEntity.class, WorkoutEntity.class, WorkoutLibraryEntity.class}, version = 1, exportSchema = false)
@TypeConverters({Converter.class})
public abstract class AppDatabase extends RoomDatabase {
private static final String TAG = "AppDatabase";
private static AppDatabase sInstance;
@VisibleForTesting
public static final String DATABASE_NAME = "ig_db";
public abstract BodySectionDao bodySectionDao();
public abstract ExerciseDao exerciseDao();
public abstract WorkoutDao workoutDao();
public abstract SetRecordDao setRecordDao();
private final MutableLiveData<Boolean> mIsDatabaseCreated = new MutableLiveData<>();
public static AppDatabase getInstance(final Context context) {
Log.d(TAG, "getInstance()");
if (sInstance == null) {
synchronized (AppDatabase.class) {
if (sInstance == null) {
sInstance = buildDatabase(context.getApplicationContext());
sInstance.updateDatabaseCreated(context.getApplicationContext());
}
}
}
return sInstance;
}
private static AppDatabase buildDatabase(final Context appContext) {
Log.d(TAG, "build database");
return Room.databaseBuilder(appContext, AppDatabase.class, DATABASE_NAME)
.addCallback(new Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
Executors.newSingleThreadScheduledExecutor().execute(new Runnable() {
@Override
public void run() {
try {
AppDatabase database = AppDatabase.getInstance(appContext);
List<String> groups = Arrays.asList(appContext.getResources().getStringArray(R.array.groups));
populateDatabase(appContext, database, groups);
database.setDatabaseCreated();
} catch (IOException e) {
Log.d(TAG, e.toString());
}
}
});
}
@Override
public void onOpen(@NonNull SupportSQLiteDatabase db) {
super.onOpen(db);
}
}).build();
}
/**
* Check whether the database already exists and expose it via {@link #getDatabaseCreated()}
*/
private void updateDatabaseCreated(final Context context) {
Log.d(TAG, "updatedatabasecreated");
if (context.getDatabasePath(DATABASE_NAME).exists()) {
setDatabaseCreated();
}
}
private void setDatabaseCreated(){
Log.d(TAG, "setdatabasecreated");
mIsDatabaseCreated.postValue(true);
}
public LiveData<Boolean> getDatabaseCreated() {
Log.d(TAG, "getdatabasecreated");
return mIsDatabaseCreated;
}
private static void populateDatabase(final Context context, final AppDatabase db, final List<String> groups) throws IOException {
//insert the body parts
Log.d(TAG, "populateDatabase");
List<BodySectionEntity> list = new ArrayList<>();
for (String section : groups) {
list.add(new BodySectionEntity(section));
}
db.bodySectionDao().insertAll(list);
//insert the exercise data
InputStream inputStream = context.getResources().openRawResource(R.raw.exercise_data);
List<ExerciseEntity> exerciseEntities = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = reader.readLine()) != null) {
Log.i("IGv2", "inside while");
String[] strings = TextUtils.split(line, ",");
exerciseEntities.add(new ExerciseEntity(
strings[0].trim(),
findBodySectionKey(strings[1], groups),
strings[2].trim(),
strings[3].trim(),
strings[4].trim(),
strings[5].trim()));
}
Log.i("IGv2", "size: " + exerciseEntities.size());
db.exerciseDao().insertAll(exerciseEntities);
Log.i("IGv2", "exercises entered");
}
}
//grabs the correct id for the COL_BODY_SECTION_ID column and returns it
private static int findBodySectionKey(String part, final List<String> groups) {
Log.d("IGv2", "findboydsectionkey");
int index = groups.indexOf(part);
return ++index;
}
}
ExerciseDao
@Dao
public interface ExerciseDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAll(List<ExerciseEntity> exercises);
@Query("Select * From exercise Order By body_section_id, exercise ASC")
LiveData<List<ExerciseEntity>> getAllExercises();
}
WorkoutFragment
…
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewModel = ViewModelProviders.of(this).get(WorkoutViewModel.class);
mViewModel.getAllExercises().observe(this, new Observer<List<ExerciseEntity>>() {
@Override
public void onChanged(List<ExerciseEntity> exerciseEntities) {
if (exerciseEntities != null) {
Toast.makeText(getContext(), "Size: " + exerciseEntities.size(), Toast.LENGTH_SHORT).show();
mExerAdapter.setExerciseList(exerciseEntities);
}
}
});
mWorkoutAdapter.setWorkout(mViewModel.getWorkout());
}
如果需要更多,请告知。预先感谢
答案 0 :(得分:0)
我发现此修复程序是在AppDatabase的创建中进行的,该创建的最底层是db.exerciseDao().insertAll(exerciseEntities);
,我试图用500多个记录进行插入。当我在其周围放置一个for语句并分别进行操作时,它没有任何问题。我在网上找到其他消息来源,说使用SQLite事务一次可以处理大量插入操作,而且SQLite一次只能处理500个插入操作。无论哪种方式,for语句都能解决问题