从两天开始,我试图解决我的问题,我引用了这里讨论的每个解决方案并尽一切可能,仍然继续显示Sql连接被泄露。由于这个应用程序不稳定,下面是我的dBhelper代码。它是一个测验应用程序
private static String DB_NAME = "NavyDb6.db";
private static String DB_PATH = "";
private SQLiteDatabase mDataBase;
private Context mContext = null;
public DbHelper(Context context) {
super(context, DB_NAME, null, 1);
DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
File file = new File(DB_PATH + "NavyDb6.db");
if (file.exists())
openDataBase(); // Add this line to fix db.insert can't insert values
this.mContext = context;
}
public void openDataBase() {
String myPath = DB_PATH + DB_NAME;
mDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}
public void copyDataBase() throws IOException {
try {
InputStream myInput = mContext.getAssets().open(DB_NAME);
String outputFileName = DB_PATH + DB_NAME;
OutputStream myOutput = new FileOutputStream(outputFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0)
myOutput.write(buffer, 0, length);
myOutput.flush();
myOutput.close();
myInput.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private boolean checkDataBase() {
SQLiteDatabase tempDB = null;
try {
String myPath = DB_PATH + DB_NAME;
tempDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
} catch (SQLiteException e) {
e.printStackTrace();
}
if (tempDB != null)
tempDB.close();
return tempDB != null ? true : false;
}
public void createDataBase() throws IOException {
boolean isDBExists = checkDataBase();
if (isDBExists) {
} else {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onCreate(SQLiteDatabase db) {}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
//We need improve this function to optimize process from Playing
public List<Question> getQuestionMode(String mode) {
List<Question> listQuestion = new ArrayList<>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor c;
int limit = 0;
if (mode.equals(Common.MODE.EASY.toString()))
limit = 20;
else if (mode.equals(Common.MODE.MEDIUM.toString()))
limit = 20;
else if (mode.equals(Common.MODE.HARD.toString()))
limit = 30;
else if (mode.equals(Common.MODE.HARDEST.toString()))
limit = 30;
try {
c = db.rawQuery(String.format("SELECT * FROM Question ORDER BY Random() LIMIT %d", limit), null);
if (c == null) return null;
c.moveToFirst();
do {
int Id = c.getInt(c.getColumnIndex("ID"));
//int cid= c.getInt(c.getColumnIndex("C_ID"));
String Qus = c.getString(c.getColumnIndex("Qus"));
String AnswerA = c.getString(c.getColumnIndex("AnswerA"));
String AnswerB = c.getString(c.getColumnIndex("AnswerB"));
String AnswerC = c.getString(c.getColumnIndex("AnswerC"));
String AnswerD = c.getString(c.getColumnIndex("AnswerD"));
String CorrectAnswer = c.getString(c.getColumnIndex("CorrectAnswer"));
Question question = new Question(Id, Qus, AnswerA, AnswerB, AnswerC, AnswerD, CorrectAnswer);
listQuestion.add(question);
db.close();
}
while (c.moveToNext());
c.close();
} catch (Exception e) {
e.printStackTrace();
}
this.close();
return listQuestion;
}
用于更新分数
public void insertScore(int score) {
String query = "INSERT INTO Rank(Score) VALUES(" + score + ")";
mDataBase.execSQL(query);
}
public List<Rank> getRanking() {
List<Rank> listRanking = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery("SELECT * FROM Rank Order By Score DESC LIMIT 5;", null);
try {
if (c == null) return null;
c.moveToNext();
do {
int Id = c.getInt(c.getColumnIndex("ID"));
int Score = c.getInt(c.getColumnIndex("Score"));
Rank ranking = new Rank(Id, Score);
listRanking.add(ranking);
} while (c.moveToNext());
} catch (Exception e) {
e.printStackTrace();
}
finally {
c.close();
db.close();
}
return listRanking;
}
答案 0 :(得分:0)
在getQuestionMode
方法中,您做错了多件事。那些是:
另外,我会避免这一行if (c == null) return null;
。
我建议使用singleton pattern来访问数据。
要解决当前问题,请尝试以下操作:
public List<Question> getQuestionMode(String mode) {
List<Question> listQuestion = new ArrayList<>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor c = null;
int limit = 0;
if (mode.equals(Common.MODE.EASY.toString()))
limit = 20;
else if (mode.equals(Common.MODE.MEDIUM.toString()))
limit = 20;
else if (mode.equals(Common.MODE.HARD.toString()))
limit = 30;
else if (mode.equals(Common.MODE.HARDEST.toString()))
limit = 30;
try {
c = db.rawQuery(String.format("SELECT * FROM Question ORDER BY Random() LIMIT %d", limit), null);
if(c.moveToFirst()) {
do {
int Id = c.getInt(c.getColumnIndex("ID"));
//int cid= c.getInt(c.getColumnIndex("C_ID"));
String Qus = c.getString(c.getColumnIndex("Qus"));
String AnswerA = c.getString(c.getColumnIndex("AnswerA"));
String AnswerB = c.getString(c.getColumnIndex("AnswerB"));
String AnswerC = c.getString(c.getColumnIndex("AnswerC"));
String AnswerD = c.getString(c.getColumnIndex("AnswerD"));
String CorrectAnswer = c.getString(c.getColumnIndex("CorrectAnswer"));
Question question = new Question(Id, Qus, AnswerA, AnswerB, AnswerC, AnswerD, CorrectAnswer);
listQuestion.add(question);
}
while (c.moveToNext());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(null != c)
c.close();
if(null != db)
db.close();
}
return listQuestion;
}
更新
您仍然在openDataBase()
方法中拥有一个开放数据库。同时将finally块添加到checkDataBase()
。
您可以尝试将帮助程序重写为this(请参阅示例!)。