Sqlite连接在android studio中泄露,尽管一切都已关闭

时间:2017-02-20 14:30:31

标签: android sqlite android-studio memory-leaks android-sqlite

从两天开始,我试图解决我的问题,我引用了这里讨论的每个解决方案并尽一切可能,仍然继续显示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;

}

1 个答案:

答案 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(请参阅示例!)。