房间未在一张桌子中保留数据

时间:2018-11-14 01:43:42

标签: android android-room android-livedata

打开后,我的应用程序可以正常工作。它能够从原始文件夹中的文本文件中预填充数据库。当我打开显示练习列表的片段时,查询运行良好,并且可以看到整个列表。如果我按返回按钮完全退出应用程序,然后重新输入,没问题,列表将再次填充。问题是当我按“最近”按钮并单击“全部关闭”时。当我重新输入该应用程序时,所有练习的查询均不产生任何结果,并且该列表为空。我搜寻了高低,什么也没找到。希望所附的代码足以诊断问题。 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());
}

如果需要更多,请告知。预先感谢

1 个答案:

答案 0 :(得分:0)

我发现此修复程序是在AppDatabase的创建中进行的,该创建的最底层是db.exerciseDao().insertAll(exerciseEntities);,我试图用500多个记录进行插入。当我在其周围放置一个for语句并分别进行操作时,它没有任何问题。我在网上找到其他消息来源,说使用SQLite事务一次可以处理大量插入操作,而且SQLite一次只能处理500个插入操作。无论哪种方式,for语句都能解决问题