1

from two days I'm trying to solve my issue i'd referred to every Solutions discussed over here and did all possibility, still it keeps on showing Sql connection is leaked. due to this application is unstable below is my dBhelper code.It is an Quiz app

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;
}

for updating Score

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;

}
gusain.jr
  • 76
  • 10

1 Answers1

0

There are multiple things you did wrong in the getQuestionMode method. Those being:

  • closing the db connection after reading the first item
  • closing cursor outside finally block

Also, I would avoid this line if (c == null) return null;.

I would recommend using singleton pattern to access data.

To fix your current issue try this:

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;
}

Update:

You still have an open database in openDataBase() method. Also add finally block to checkDataBase().

You could try rewriting your helper to this(See the example!).

Community
  • 1
  • 1
Goran
  • 153
  • 2
  • 9
  • Appreciate you time But still i didn't work same warning keeps on showing – gusain.jr Feb 20 '17 at 15:44
  • 2265-2274/com.example.kdeepti.navyquiz D/dalvikvm: GC_FOR_ALLOC freed 4K, 50% free 26199K/51616K, paused 20ms, total 20ms 2265-2274/com.example.kdeepti.navyquiz W/SQLiteConnectionPool: A SQLiteConnection object for database 'xx' was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed. 2038-2038/com.google.android.gms D/dalvikvm: GC_FOR_ALLOC freed 699K, 25% free 4863K/6424K, paused 9ms, total 9ms – gusain.jr Feb 20 '17 at 16:00
  • Glad to be of assistance :) Don't forget to mark the question as answered if you find it fitting. – Goran Feb 20 '17 at 16:45
  • I made changes it works fine in emulator and now i tried to run on my mobile but the app is not working(Force close)..i undo the changes and now its working in mobile device(unstable form). – gusain.jr Feb 21 '17 at 04:03
  • Show me your error log of app on mobile device please. – Goran Feb 21 '17 at 06:45
  • I am guessing you solved the issue since you accepted the answer? – Goran Feb 21 '17 at 14:55