嗨,我正在尝试用一系列问题填充数据库,但是我无法让问题填充表以检索到应用程序中。我收到此错误(附加了完整的错误日志):
java.lang.RuntimeException:无法启动活动ComponentInfo {com.example.hp.demo / com.example.hp.demo.MainActivityQuizBasics}:java.lang.IllegalStateException:getDatabase递归调用
error log
在过去的一个小时中,我一直在尝试尝试解决此问题,但是我无法解决该问题。我知道这与在addQuestions方法中调用getWritableDatabase函数有关,但我不知道该如何解决。如果有人有任何建议,将不胜感激。
MainActivityQuizBasics
package com.example.hp.demo;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import com.example.hp.demo.DbHelper.DatabaseHelper;
import com.example.hp.demo.Model.QuestionBasics;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class MainActivityQuizBasics extends AppCompatActivity {
public int score = 0;
public ArrayList<String> wrongQuestListBasics = new ArrayList<String>();
public ArrayList<String> selectedBasics = new ArrayList<String>();
public ArrayList<String> actualAnswerBasics = new ArrayList<String>();
List<QuestionBasics> quesList1;
int ctr1 = 1;
QuestionBasics currentQ1;
TextView txtQuestion1;
RadioGroup grp;
RadioButton rda1, rdb1, rdc1, rdd1;
Button butNext1;
Random random1 = new Random();
ArrayList<Integer> list = new ArrayList<Integer>();
TextView textViewTime1;
int number;
ProgressBar progressBar;
int progress = 1;
String tableName = "", catName = "";
TextView qstnNo;
DatabaseHelper mDBHlpr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_questions_basics);
mDBHlpr = new DatabaseHelper(this,"blah blah blah", null,1);
QuestionBasics myQuestion = new QuestionBasics(
"What is note X?",
"It's not a note",
"A note that only xylophones can make.",
"A note when a bowed instrument is played with two bows",
"A synthesised x wave","It's not a note",
"Basics");
//mDBHlpr.addQuestionsBasics(myQuestion);
List<QuestionBasics> mylist = mDBHlpr.getAllQuestions1(DatabaseHelper.TABLE_QUEST1,"doesnotmatter");
for (QuestionBasics q: mylist) {
Log.d("QUESTIONS",q.getQUESTION1());
}
qstnNo = findViewById(R.id.qstnNo);
Intent iin = getIntent();
Bundle b = iin.getExtras();
if (b != null) {
tableName = (String) b.get("table_name");
catName = (String) b.get("level_name");
Log.d("Table Name", tableName);
Log.d("Level Name", catName);
}
number = 0;
//DatabaseHelper db = new DatabaseHelper(this);
//db.addBasicsTable(tableName,catName);
//timer
textViewTime1 = findViewById(R.id.textViewTime);
final CounterClass timer = new CounterClass(1800000, 1000);
timer.start();
// quesList1 = db.getAllQuestions1("questBasics", catName);
// for (int i = 0; i < 50; i++) {
// while (true) {
// int next = random1.nextInt(50);
// if (!list.contains(next)) {
// list.add(next);
// break;
// }
// }
// }
//layout content
currentQ1 = quesList1.get(0);
txtQuestion1 = findViewById(R.id.textView1);
rda1 = findViewById(R.id.radio0);
rdb1 = findViewById(R.id.radio1);
rdc1 = findViewById(R.id.radio2);
rdd1 = findViewById(R.id.radio3);
butNext1 = findViewById(R.id.button1);
setQuestionView();
grp = findViewById(R.id.radioGroup1);
butNext1.setEnabled(false);
grp.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
if (i == R.id.radio0 || i == R.id.radio1 || i == R.id.radio2 || i == R.id.radio3)
butNext1.setEnabled(true);
}
});
progressBar = findViewById(R.id.progressBar);
progressBar.setMax(30);
progressBar.setProgress(1);
//checking answer
butNext1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progress = progress + 1;
progressBar.setProgress(progress);
RadioButton answer = findViewById(grp.getCheckedRadioButtonId());
//Log.d("yourans", currentQ1.getANSWER1() + " " + answer.getText());
if (currentQ1.getANSWER1().equals(answer.getText())) {
score++;
//Log.d("score", "Your score" + score1);
} else {
wrongQuestListBasics.add(number, currentQ1.getQUESTION1());
selectedBasics.add(number, answer.getText().toString());
actualAnswerBasics.add(number, currentQ1.getANSWER1());
number++;
}
grp.clearCheck();
butNext1.setEnabled(false);
//finishing quiz
if (ctr1 < 31) {
if (ctr1 == 30) {
butNext1.setText("End Quiz");
}
currentQ1 = quesList1.get(list.get(ctr1));
setQuestionView();
} else {
timer.onFinish();
timer.cancel();
}
}
});
}
public void showResult() {
Intent intent = new Intent(MainActivityQuizBasics.this, ResultActivity.class);
Bundle b = new Bundle();
b.putInt("scoreBasics", score);//Your score
b.putString("section", "questBasics");//Your table name
b.putString("category", catName);//Your category name
intent.putStringArrayListExtra("wrongQuestions", wrongQuestListBasics);
intent.putStringArrayListExtra("selectedAnswer", selectedBasics);
intent.putStringArrayListExtra("actualAnswer", actualAnswerBasics);
intent.putExtras(b); //Put your score to your next Intent
startActivity(intent);
finish();
}
private void setQuestionView() {
txtQuestion1.setText(currentQ1.getQUESTION1());
rda1.setText(currentQ1.getOPTA1());
rdb1.setText(currentQ1.getOPTB1());
rdc1.setText(currentQ1.getOPTC1());
rdd1.setText(currentQ1.getOPTD1());
if (ctr1 < 10)
qstnNo.setText("0" + ctr1 + "/30");
else
qstnNo.setText("" + ctr1 + "/30");
ctr1++;
}
}
}
}
编辑-实施建议的更改
数据库助手
package com.example.hp.demo.DbHelper;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.example.hp.demo.Model.QuestionBasics;
import com.example.hp.demo.Model.QuestionChords;
import com.example.hp.demo.Model.QuestionScales;
import java.util.ArrayList;
import java.util.List;
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "Quiz.db";
public static final String TABLE_SCORE = "score";
public static final String SCORE_KEY_ID = "id";
public static final String SCORE_KEY_SECTION = "section";
public static final String SCORE_KEY_CAT = "category";
public static final String SCORE_KEY_SCORE = "score";
private static final String KEY_ID = "id";
private static final String KEY_QUES = "question";
private static final String KEY_ANSWER = "answer"; //correct option
private static final String KEY_OPTA = "opta"; //option a
private static final String KEY_OPTB = "optb"; //option b
private static final String KEY_OPTC = "optc"; //option c
private static final String KEY_OPTD = "optd"; //option d
private static final String KEY_CAT = "category"; //category
private static final String TABLE_QUEST = "questScales";
public static final String TABLE_QUEST1 = "questBasics";
private static final String TABLE_QUEST2 = "questChords";
private SQLiteDatabase db;
public DatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, DATABASE_NAME, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
this.db = db;
String basicsTableCreate = "CREATE TABLE IF NOT EXISTS " + TABLE_QUEST1 + " ( "
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_QUES
+ " TEXT, " + KEY_ANSWER + " TEXT, " + KEY_OPTA + " TEXT, "
+ KEY_OPTB + " TEXT, " + KEY_OPTC + " TEXT, " + KEY_OPTD + " TEXT, " + KEY_CAT + " TEXT)";
db.execSQL(basicsTableCreate);
addQuestionsBasics(db)
String scoresTableCreate = "CREATE TABLE IF NOT EXISTS " + TABLE_SCORE + " ( "
+ SCORE_KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + SCORE_KEY_SECTION
+ " TEXT, " + SCORE_KEY_CAT + " TEXT, " + SCORE_KEY_SCORE + " INTEGER)";
db.execSQL(scoresTableCreate);
}
private void addQuestionsBasics(SQLiteDatabase db) {
QuestionBasics q101 = new QuestionBasics("What is pitch?", "The length of a sound", "The overall quality of a sound", "The highness or lowness of a sound", "The volume of a sound", "The highness or lowness of a sound", "B");
this.addQuestionBasics(q101,db);
QuestionBasics q102 = new QuestionBasics("What is 'timbre'?", "The ove", "format it", "compile it", "hardware it", "format it", "B");
this.addQuestionBasics(q102,db);
QuestionBasics q103 = new QuestionBasics("What is rhythm?", "The sound a metronome makes", "The organisation of music through time", "A beat that repeats itself", "The amount of beats in a bar", "The organisation of music through time", "B");
this.addQuestionBasics(q103,db);
QuestionBasics q104 = new QuestionBasics("What is harmony?", "A series of pitches creating a musical statement", "The result of multiple notes played simultaneously", "A strong match between 2 different notes", "The sound a chord makes when the notes are in the correct key", "A strong match between 2 different notes", "B");
this.addQuestionBasics(q104,db);
QuestionBasics q105 = new QuestionBasics("What is a 'melody'?", "A strong rhythm that keeps the tune going", "A series of pitches that form a musical statement", "A set of chords that works well together", "A short motif to transition 2 sections of a song", "A series of pitches that form a musical statement", "B");
this.addQuestionBasics(q105,db);
QuestionBasics q106 = new QuestionBasics("What is 'dynamics'?", "Changes in textures, such as switching instruments", "Variations in loudness and softness", "The movement of music between different keys", "The way the melody of a song integrates with the chords", "Variations in loudness and softness", "B");
this.addQuestionBasics(q106,db);
QuestionBasics q107 = new QuestionBasics("What two note note pairs have no sharp or flat between them?", "DE, AB", "DF, BC", "BC ,DE", "EF, BC", "EF, BC", "B");
this.addQuestionBasics(q107,db);
QuestionBasics q108 = new QuestionBasics("What is pitch?", "The length of a sound", "The overall quality of a sound", "The highness or lowness of a sound", "The volume of a sound", "The highness or lowness of a sound", "B");
this.addQuestionBasics(q108,db);
QuestionBasics q109 = new QuestionBasics("What is 'timbre'?", "The ove", "format it", "compile it", "hardware it", "format it", "B");
this.addQuestionBasics(q109,db);
QuestionBasics q110 = new QuestionBasics("What is rhythm?", "The sound a metronome makes", "The organisation of music through time", "A beat that repeats itself", "The amount of beats in a bar", "The organisation of music through time", "B");
this.addQuestionBasics(q110,db);
//shortened for testing
}
public void addQuestionsBasics(QuestionBasics quest) {
addQuestionBasics(quest,this.getWritableDatabase());
}
public void addQuestionBasics(QuestionBasics quest,SQLiteDatabase db) {
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_QUES, quest.getQUESTION1());
contentValues.put(KEY_ANSWER, quest.getANSWER1());
contentValues.put(KEY_OPTA, quest.getOPTA1());
contentValues.put(KEY_OPTB, quest.getOPTB1());
contentValues.put(KEY_OPTC, quest.getOPTC1());
contentValues.put(KEY_OPTD, quest.getOPTD1());
contentValues.put(KEY_CAT, quest.getCATEGORY1());
// Inserting Row
db.insert(TABLE_QUEST1, null, contentValues);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_QUEST1);
onCreate(db);
}
public List<QuestionBasics> getAllQuestions1(String tname, String lname) {
List<QuestionBasics> quesList1 = new ArrayList<QuestionBasics>();
String selectQuery1 = "SELECT * FROM " + tname + " WHERE " + KEY_CAT + " = '" + lname + "'";
db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery1, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
QuestionBasics quest1 = new QuestionBasics();
quest1.setID1(cursor.getInt(0));
quest1.setQUESTION1(cursor.getString(1));
quest1.setANSWER1(cursor.getString(2));
quest1.setOPTA1(cursor.getString(3));
quest1.setOPTB1(cursor.getString(4));
quest1.setOPTC1(cursor.getString(5));
quest1.setOPTD1(cursor.getString(6));
quesList1.add(quest1);
} while (cursor.moveToNext());
}
// return quest list
return quesList1;
}
public List<QuestionScales> getAllQuestions(String tname, String lname) {
List<QuestionScales> quesList1 = new ArrayList<QuestionScales>();
String selectQuery1 = "SELECT * FROM " + tname + " WHERE " + KEY_CAT + " = '" + lname + "'";
db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery1, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
QuestionScales quest1 = new QuestionScales();
quest1.setID(cursor.getInt(0));
quest1.setQUESTION(cursor.getString(1));
quest1.setANSWER(cursor.getString(2));
quest1.setOPTA(cursor.getString(3));
quest1.setOPTB(cursor.getString(4));
quest1.setOPTC(cursor.getString(5));
quest1.setOPTD(cursor.getString(6));
quesList1.add(quest1);
} while (cursor.moveToNext());
}
// return quest list
return quesList1;
}
public boolean insertScoreBasics(int scoreBasics, String tname, String cname) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(SCORE_KEY_SECTION, tname);
contentValues.put(SCORE_KEY_CAT, cname);
contentValues.put(SCORE_KEY_SCORE, scoreBasics);
long resultscore = db.insert(TABLE_SCORE, null, contentValues);
if (resultscore == -1)
return false;
else
return true;
}
public int getScoreBasics() {
Cursor c;
SQLiteDatabase db = this.getWritableDatabase();
String sqlSelectQuery = "SELECT MAX(" + SCORE_KEY_SCORE + ") FROM " + TABLE_SCORE + " WHERE " + SCORE_KEY_SECTION + " = '" + TABLE_QUEST1 + "' AND " + SCORE_KEY_CAT + " = " + "'I'";
c = db.rawQuery(sqlSelectQuery, null);
c.moveToFirst();
int x = c.getInt(0);
return x;
}
}
xml文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:padding="10dp"
tools:context=".MainActivityQuizBasics">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|left"
android:background="@drawable/rect_background_pink">
<TextView
android:id="@+id/qstnNo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:singleLine="true"
android:text="01/30"
android:textColor="@color/white"
android:textSize="20dp"
android:textStyle="bold" />
</RelativeLayout>
<TextView
android:id="@+id/textViewTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="05:00"
android:textColor="@color/colorAccent"
android:textSize="25dp"
android:textStyle="bold" />
</RelativeLayout>
<ProgressBar
android:id="@+id/progressBar"
style="@style/CustomProgressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:max="30" />
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/colorPrimaryDark" />
<RadioGroup
android:id="@+id/radioGroup1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_weight="0.03">
<RadioButton
android:id="@+id/radio0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="false"
android:text="RadioButton"
android:textColor="@color/colorPrimaryDark" />
<RadioButton
android:id="@+id/radio1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RadioButton"
android:textColor="@color/colorPrimaryDark" />
<RadioButton
android:id="@+id/radio2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RadioButton"
android:textColor="@color/colorPrimaryDark" />
<RadioButton
android:id="@+id/radio3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RadioButton"
android:textColor="@color/colorPrimaryDark" />
</RadioGroup>
</LinearLayout>
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="30dp"
android:layout_marginTop="15dp"
android:layout_marginRight="30dp"
android:background="@color/deeppurple"
android:fontFamily="sans-serif"
android:text="NEXT"
android:textColor="#fff" />
最佳答案
您的问题(重复出现的问题)是您使用的方法将调用getWriteableDatabase并尝试在正确打开数据库之前尝试通过getWritableDatabase打开数据库。
例如在onCreate中,您可以调用addQuestionsBasics();那就是您获得递归的地方。而不是使用它来引用数据库,您需要将传递给onCreate方法的SQliteDatabase传递给addQuestionsBasics();。并使用它。
如此更改addQuestionsBasics(the_question);至
:-
private void addQuestionsBasics(thequestion, SQliteDatabase db) {
QuestionBasics q101 = new QuestionBasics("What is pitch?", "The length of a sound", "The overall quality of a sound", "The highness or lowness of a sound", "The volume of a sound", "The highness or lowness of a sound", "B");
db.addQuestionBasics(q101); //<<<<<<<<<< CHANGED
QuestionBasics q102 = new QuestionBasics("What is 'timbre'?", "The ove", "format it", "compile it", "hardware it", "format it", "B");
db.addQuestionBasics(q102); //<<<<<<<<<< CHANGED
....... and so on
并在onCreate方法中更改为使用:-
db.execSQL(basicsTableCreate);
addQuestionsBasics(db);
您还需要公共的addQuestionsBasics方法,以能够在有或没有提供数据库的情况下处理呼叫。
为此,请使用2个带签名的公共void addQuestionsBasics方法(较短的仅包含一个问题,因为它的参数可以调用较长的版本)
例如:-
String basicsTableCreate = "CREATE TABLE IF NOT EXISTS " + TABLE_QUEST1 + " ( "
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_QUES
+ " TEXT, " + KEY_ANSWER + " TEXT, " + KEY_OPTA + " TEXT, "
+ KEY_OPTB + " TEXT, " + KEY_OPTC + " TEXT, " + KEY_OPTD + " TEXT, " + KEY_CAT + " TEXT)";
db.execSQL(basicsTableCreate);
addQuestionsBasics(db);
//............. code shortened for test ..........
}
private void addQuestionsBasics(SQLiteDatabase db) { //<<<<<<<<<< CHANGED
QuestionBasics q101 = new QuestionBasics("What is pitch?", "The length of a sound", "The overall quality of a sound", "The highness or lowness of a sound", "The volume of a sound", "The highness or lowness of a sound", "B");
this.addQuestionBasics(q101,db);
QuestionBasics q102 = new QuestionBasics("What is 'timbre'?", "The ove", "format it", "compile it", "hardware it", "format it", "B");
this.addQuestionBasics(q102,db);
//............. code shortened for test ..........
}
//<<<<<<<<<< NEW >>>>>>>>>>
public void addQuestionsBasics(QuestionBasics quest) {
addQuestionBasics(quest,this.getWritableDatabase());
}
public void addQuestionBasics(QuestionBasics quest, SQLiteDatabase db) { //<<<<<<<<<< CHANGED
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_QUES, quest.getQUESTION1());
contentValues.put(KEY_ANSWER, quest.getANSWER1());
contentValues.put(KEY_OPTA, quest.getOPTA1());
contentValues.put(KEY_OPTB, quest.getOPTB1());
contentValues.put(KEY_OPTC, quest.getOPTC1());
contentValues.put(KEY_OPTD, quest.getOPTD1());
contentValues.put(KEY_CAT, quest.getCATEGORY1());
// Inserting Row
dbase.insert(TABLE_QUEST1, null, contentValues);
重要
对于其他表,要添加的所有行以及所有相应方法,都需要重复上述操作。
基于以上内容(仅注意两个问题),在活动中使用以下内容(通过调整getAllQuestions1方法以选择所有行):
public class MainActivity extends AppCompatActivity {
DatabaseHelper mDBHlpr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDBHlpr = new DatabaseHelper(this,"blah blah blah", null,1);
QuestionBasics myQuestion = new QuestionBasics(
"What is note X?",
"It's not a note",
"A note that only xylophones can make.",
"A note when a bowed instrument is played with two bows",
"A synthesised x wave","Something Esle",
"Wierdness");
mDBHlpr.addQuestionsBasics(myQuestion); //<<<<<<<<<< ADD another question
List<QuestionBasics> mylist = mDBHlpr.getAllQuestions1(DatabaseHelper.TABLE_QUEST1,"doesnotmatter");
for (QuestionBasics q: mylist) {
Log.d("QUESTIONS",q.getQUESTION1());
}
}
}
其结果是:-
05-23 11:05:48.911 22414-22414/? D/QUESTIONS: What is pitch?
05-23 11:05:48.911 22414-22414/? D/QUESTIONS: What is 'timbre'?
05-23 11:05:48.911 22414-22414/? D/QUESTIONS: What is note X?