Я получаю исключение не закрытый объект базы данных в SQLite (Android), но я явно закрываю свою базу данных ... Справка? - PullRequest
9 голосов
/ 09 февраля 2011

Вот ошибка:

02-08 16: 35: 00.899: ОШИБКА / База данных (468): android.database.sqlite.DatabaseObjectNotClosedException: приложение не закрывало курсор или объект базы данных, который был открыт здесь

Кроме, ну, я. Вот метод, где эта проблема возникает:

    public static void getUpdates(String username, Context context) {
    HttpClient httpClient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost("http://10.0.2.2/tag/appgetfriendinfo.php");

    try {
        List<NameValuePair> nVPs = new ArrayList<NameValuePair>();
        nVPs.add(new BasicNameValuePair("username", username));

        httpPost.setEntity(new UrlEncodedFormEntity(nVPs));
        HttpResponse response = httpClient.execute(httpPost);

        ResponseHandler<String> rHandler = new BasicResponseHandler();
        String result = rHandler.handleResponse(response);

        JSONArray jArray = new JSONArray(result);
        for(int i = 0; i < jArray.length(); i++) {
            JSONObject jObj = jArray.getJSONObject(i);
            String userCheck = jObj.getString("username");
            TagDBAdapter dbHelper = new TagDBAdapter(context);
            dbHelper.open();//OPENING THE DATABASE
            Contact contact = new Contact();

            String first = jObj.getString("firstname");
            String last = jObj.getString("lastname");
            String name = first + " " + last;

            contact.setUsername(jObj.getString("username"));
            contact.setFirstName(first);
            contact.setLastName(last);
            contact.setName(name);
            contact.setPhoneNumber(jObj.getString("phonenumber"));
            contact.setEmail(jObj.getString("email"));
            contact.setHomePhone(jObj.getString("homephone"));
            contact.setWorkPhone(jObj.getString("workphone"));

            if(dbHelper.checkForExisting(userCheck) == true) {
                dbHelper.createContact(contact);
            }
            else {
                dbHelper.updateContactAuto(userCheck, contact);
            }
            dbHelper.close();//CLOSING THE DATABASE
        }

    } catch(ClientProtocolException e) {
        Log.e("GETUPDATES", "CPE", e);
        e.printStackTrace();
    } catch(IOException e) {
        Log.e("GETUPDATES", "IOE", e);
        e.printStackTrace();
    } catch(JSONException e) {
        Log.e("GETUPDATES", "JSONE", e);
        e.printStackTrace();
    }
}

Как вы можете видеть в строках, которые я отметил в // комментариях, я открываю и закрываю базу данных, но все равно получаю сообщение об ошибке. Вот что странно: источник ошибки находится в методе open () SQLite.

ОШИБКА / База данных (468): на com.tagapp.android.TagDBAdapter.open (TagDBAdapter.java:62)

Что это:

    /**THESE ARE MY DBADAPTER'S OPEN AND CLOSE METHODS*/

    public TagDBAdapter open() throws SQLException {
    mDBHelper = new DatabaseHelper(m_context);
    mDb = mDBHelper.getWritableDatabase();
    return this;
}

public void close() {
    mDBHelper.close();
}

Это прямо из учебника Google по блокнотам, и они работали на 100% для меня в разных случаях. У кого-нибудь есть представление о том, что здесь происходит? Большое спасибо.

Ответы [ 2 ]

12 голосов
/ 09 февраля 2011

Проблема не в объекте базы данных, а в курсоре - у вас где-то лежит открытый курсор.

Убедитесь, что все курсоры закрыты, прежде чем закрыть базу данных. (Кстати, если вы хотите проявить фантазию, вы можете создать ContentProvider, использовать SQLiteOpenHelper и вообще не беспокоиться о его закрытии.)

0 голосов
/ 18 января 2014

Рассматривая это, я исследую похожую проблему.Одна возможность, которую я заметил, заключается в том, что если по какой-либо причине вы бросаете исключение в свой цикл, то даже если вы правильно его обрабатываете, вы выпадаете из цикла, и последний метод open () никогда не имеет соответствующего закрытия.Чтобы это исправить, вы бы хотели поместить оператор close () в блок finally {}.Кроме того, я не вижу причин создавать и открывать новый курсор для каждой итерации цикла.Переместите это за пределы цикла, чтобы был один и только один open (), и соответствующий close () - тот, что находится в блоке finally.(В качестве альтернативы у вас может быть другая конструкция try-catch внутри цикла, чтобы всегда выполнялся close ().)

Пример:

public static void getUpdates(String username, Context context) {
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://10.0.2.2/tag/appgetfriendinfo.php");
TagDBAdapter dbHelper;  // DECLARE THIS HERE SO IT CAN BE ACCESSED OUTSIDE OF try BLOCK
try {
    List<NameValuePair> nVPs = new ArrayList<NameValuePair>();
    nVPs.add(new BasicNameValuePair("username", username));

    httpPost.setEntity(new UrlEncodedFormEntity(nVPs));
    HttpResponse response = httpClient.execute(httpPost);

    ResponseHandler<String> rHandler = new BasicResponseHandler();
    String result = rHandler.handleResponse(response);

    JSONArray jArray = new JSONArray(result);

    // MOVED TO OUTSIDE OF LOOP
    dbHelper = new TagDBAdapter(context);
    dbHelper.open();//OPENING THE DATABASE
    for(int i = 0; i < jArray.length(); i++) {
        JSONObject jObj = jArray.getJSONObject(i);
        String userCheck = jObj.getString("username");
        Contact contact = new Contact();

        String first = jObj.getString("firstname");
        String last = jObj.getString("lastname");
        String name = first + " " + last;

        contact.setUsername(jObj.getString("username"));
        contact.setFirstName(first);
        contact.setLastName(last);
        contact.setName(name);
        contact.setPhoneNumber(jObj.getString("phonenumber"));
        contact.setEmail(jObj.getString("email"));
        contact.setHomePhone(jObj.getString("homephone"));
        contact.setWorkPhone(jObj.getString("workphone"));

        if(dbHelper.checkForExisting(userCheck) == true) {
            dbHelper.createContact(contact);
        }
        else {
            dbHelper.updateContactAuto(userCheck, contact);
        }
    }

} catch(ClientProtocolException e) {
    Log.e("GETUPDATES", "CPE", e);
    e.printStackTrace();
} catch(IOException e) {
    Log.e("GETUPDATES", "IOE", e);
    e.printStackTrace();
} catch(JSONException e) {
    Log.e("GETUPDATES", "JSONE", e);
    e.printStackTrace();
} finally {
    dbHelper.close();//CLOSING THE DATABASE
}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...