Запуск действия из действия с использованием намерения приводит к неполученным ошибкам

#android

#Android

Вопрос:

В моей основной деятельности:

 button = (Button) findViewById(R.id.mainAddWatchButton);
button.setOnClickListener(new Button.OnClickListener() {
  public void onClick(View v) {
    startActivity(new Intent(audiovideo, CountyBrowser.class));
  }
});
  

Активность CountyBrowser запускается нормально (и ведет себя нормально, как и должно быть), но подобные вещи выводятся в LogCat:

 10-11 19:10:41.182: INFO/ActivityManager(58): Starting activity: Intent { cmp=se.ribit.bb/.CountyBrowser }
10-11 19:10:41.782: DEBUG/dalvikvm(368): GC freed 6313 objects / 354184 bytes in 114ms
10-11 19:10:41.812: INFO/dalvikvm(368): Uncaught exception thrown by finalizer (will be discarded):
10-11 19:10:41.812: INFO/dalvikvm(368): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@43d3ec38 on null that has not been deactivated or closed
10-11 19:10:41.823: INFO/dalvikvm(368):     at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
10-11 19:10:41.823: INFO/dalvikvm(368):     at dalvik.system.NativeStart.run(Native Method)
10-11 19:10:41.852: INFO/dalvikvm(368): Uncaught exception thrown by finalizer (will be discarded):
10-11 19:10:41.862: INFO/dalvikvm(368): Ljava/lang/IllegalStateException;: **Finalizing cursor android.database.sqlite.SQLiteCursor@43d3dc80 on null that has not been deactivated or closed**
10-11 19:10:41.862: INFO/dalvikvm(368):     at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
10-11 19:10:41.873: INFO/dalvikvm(368):     at dalvik.system.NativeStart.run(Native Method)
10-11 19:10:42.452: INFO/ActivityManager(58): Displayed activity se.ribit.bb/.CountyBrowser: 1198 ms (total 1198 ms)
10-11 19:10:47.702: DEBUG/dalvikvm(206): GC freed 124 objects / 5424 bytes in 154ms
10-11 19:10:52.692: DEBUG/dalvikvm(105): GC freed 2292 objects / 133288 bytes in 107ms
  

Я использую базу данных и курсоры, но в приведенных выше сообщениях содержится нулевая информация о том, делаю ли я что-то неправильно или нет. Действие работает нормально, за исключением этих журналов. Если я запускаю все в режиме отладки, эмулятор постоянно возвращает меня к Eclipse.

Я что-то здесь упускаю? Кто-нибудь хочет догадаться, что я делаю неправильно?

Ответ №1:

Я думаю, вам нужно закрыть курсоры перед приостановкой действия. В вашем методе onPause для действия, которое открывает новое действие, попробуйте закрыть курсоры.

 void onPause(){
  myCursor1.close();
  myCursor2.close();
}
  

Комментарии:

1. Привет. Извините, я был немного неясен в своем, но я использую startManagingCursor(), поэтому мне не нужно беспокоиться об этом. После долгой пошаговой отладки я наконец нашел источник ошибки (см. Следующий пост).

Ответ №2:

После долгой пошаговой отладки я нашел источник ошибки. У меня был такой метод:

 private boolean doesColumnExist(String table, int id) {
  SQLiteDatabase db = this.dbHelper.getReadableDatabase();
  String query = String.format("SELECT count(*) FROM %s WHERE %s = %s",
                                table, C_ID, id);
  Cursor c = db.rawQuery(query, null);
  c.moveToFirst();
  return (c.getInt(0) == 1);
}
  

Я еще не силен в Java, поэтому наивно думал, что курсор должен был умереть сам по себе, когда этот метод вернется, но я, очевидно, сильно ошибался в этом факте. Мне пришлось переписать метод в это:

 private boolean doesColumnExist(String table, int id) {
  SQLiteDatabase db = this.dbHelper.getReadableDatabase();
  String query = String.format("SELECT count(*) FROM %s WHERE %s = %s",
                                table, C_ID, id);
  Cursor c = db.rawQuery(query, null);
  c.moveToFirst();
  boolean retVal = (c.getInt(0) == 1);
  c.close();

  return retVal;
}
  

Теперь все заполнения LogCat исчезли.

Я никогда не понимал, что мне нужно вручную выполнять c.close(). Поскольку я новичок в Java, я думал, что Java GC справится с этим. Дальнейшее чтение в моей Java-книге доказало, что я ошибался, очень ошибался.