Мое приложение имеет меню верхнего уровня в RecyclerView, и при щелчке любого элемента открывается новое действие с подменю в новом RecyclerView. Названия пунктов меню хранятся в «tableL1» базы данных SQLite, а пункты подменю в «tableL2» в столбце «заголовки L2». Чтобы получить правильные номера строк tableL2 для любого набора заголовков, составляющих подменю, у меня есть столбец в tableL1, озаглавленный «rowrefs», каждая запись содержит смещение и предел (например, «0,15», чтобы пропустить ни одного и взять первое 15). При щелчке по пункту меню верхнего уровня эти ссылки на строки сохраняются в SharedPreferences, откуда они читаются вторым действием, когда инициируется подменю RecyclerView.
Я использую описанный здесь sqliteassethelper https://www.javahelps.com/2015/04/import-and-use-external-database-in.html и первая версия приложения работала нормально, используя следующий запрос в DatabaseAccess. java: String qL2Titles = "SELECT titleL2 **FROM "+listTable+" LIMIT "+rowRefs**; (listTable is 'tableL2' and rowrefs might be '0,15')
. Сейчас я перестраиваюсь с androidx, но этот же запрос теперь вызывает cra sh, logcat выдает следующее сообщение об ошибке:
"Причина: android .database.sqlite.SQLiteException: near «0»: синтаксическая ошибка (код 1 SQLITE_ERROR): при компиляции: SELECT titleL2 ОТ 0,15 LIMIT tableL2"
Так что, похоже, перевернул идентификатор таблицы и rowrefs поля 'при компиляции'. Я тщательно проверил свой код, чтобы убедиться, что я как-то не перевернул эти поля, но не смог найти способ, которым это могло произойти, и, как я уже сказал, первая версия работала нормально. Я исследовал сообщение об ошибке и не нашел ничего идентичного, но похожие сообщения об ошибках, по-видимому, были не очень точными c и полезными. Прежде чем что-то разгневать, я попробовал одну сумасшедшую вещь - перевернуть значения в моем запросе так: String qL2Titles = "SELECT titleL2 FROM "+rowRefs+" LIMIT "+listTable;
- что, кажется, не имеет смысла, но эй, теперь приложение работает нормально, как это. Так что я могу двигаться вперед, но я нервничаю, потому что мне не нравятся строки в моем приложении, которые кажутся бессмыслицей. Всегда ли можно доверять компиляции таким противоречащим интуитивно понятным способом? Кто-нибудь видел что-то подобное раньше или может подсказать, почему это происходит?
Из onBindViewHolder в адаптер меню верхнего уровня:
holder.menuListItemLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SharedPreferences sharedPreferences = mContext.getSharedPreferences("com.englishdreaming.appily", Context.MODE_PRIVATE);
title = mTitles.get(position);
listTable = mTables.get(position);
rowRefs = mRowrefs.get(position);
sharedPreferences.edit().putString("title", title).apply();
sharedPreferences.edit().putString("listTable", listTable).apply();
sharedPreferences.edit().putString("rowRefs", rowRefs).apply();
Log.d(TAG, "onClick: clicked on"+mTitles.get(position));
Intent intentA = new Intent(mContext, PhrasesMenuL2Activity.class);
mContext.startActivity(intentA);
}
});
Странно, это работает:
public ArrayList<String> getL2Titles() {
SharedPreferences sharedPreferences = mContext.getSharedPreferences("com.englishdreaming.appily", Context.MODE_PRIVATE);
String rowRefs = sharedPreferences.getString("rowRefs", "");
String listTable = sharedPreferences.getString("listTable", "");
String qL2Titles = "SELECT titleL2 FROM "+rowRefs+" LIMIT "+listTable;
ArrayList<String> mL2Titles = new ArrayList<>();
Cursor cursor = database.rawQuery(qL2Titles, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
mL2Titles.add(cursor.getString(0));
cursor.moveToNext();
}
cursor.close();
return mL2Titles;
}
(Изменить в ответ на комментарий Тима Бигелайзена)
ArrayLists 'mRowrefs' и 'mTables' заполняются путем вызова двух методов DatabaseAccess в initRecyclerView () в первом действии:
public void initRecyclerView(){
Log.d(TAG, "initRecyclerView: initRecyclerView called");
DatabaseAccess databaseAccess = DatabaseAccess.getInstance(this);
databaseAccess.open();
ArrayList<String> mTitles = databaseAccess.getL1Titles();
ArrayList<String> mTitleTranss = databaseAccess.getL1TitleTranss();
ArrayList<String> mRowrefs = databaseAccess.getRowrefs();
ArrayList<String> mTables = databaseAccess.getTables();
databaseAccess.close();
for (int n = 0; n < mTitles.size(); n++) {
System.out.println(mTitles.get(n));
}
RecyclerView recyclerView = findViewById(R.id.recyclerView);
PhraseMenuAdapter adapter = new PhraseMenuAdapter(this, mTitles, mTitleTranss, mImages, mRowrefs, mTables);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
и они выглядят так:
String qTables = "SELECT table_id FROM tableL1";
String qRowrefs = "SELECT rowrefs FROM tableL1";
public ArrayList<String> getRowrefs() {
ArrayList<String> mRowrefs = new ArrayList<>();
Cursor cursor = database.rawQuery(qRowrefs, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
mRowrefs.add(cursor.getString(0));
cursor.moveToNext();
}
cursor.close();
return mRowrefs;
}
public ArrayList<String> getTables() {
ArrayList<String> mTables = new ArrayList<>();
Cursor cursor = database.rawQuery(qTables, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
mTables.add(cursor.getString(0));
cursor.moveToNext();
}
cursor.close();
return mTables;
}
В моей базе данных правильно отображаются столбцы:
фрагмент базы данных