在Android中使用SimpleCursorAdapter时出现异常和崩溃

发布于 2024-12-09 02:55:36 字数 6626 浏览 0 评论 0原文

Android 新手在使用 SimpleCursorAdapter 时遇到了一些无法解决的问题。

这是代码(省略导入):

package se.ribit.bb;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class CountyBrowser extends Activity {
  private AVApplication audiovideo;
  private final String LOG_TAG = AVApplication.LOG_TAG;
  private final String TAG = "=== " + CountyBrowser.class.getSimpleName() + ": ";

  static final String[] FROM = { LocationDB.C_NAME};
  static final int[]    TO   = { R.id.locationName };

  //  DB dbHelper;
  private Cursor cursor;
  private ListView listItems;
  private SimpleCursorAdapter adapter;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.d(LOG_TAG, TAG + "onCreate");

    setContentView(R.layout.county_main_view);

    // View for the adapter 
    listItems = (ListView) findViewById(R.id.county_listview);

    // Get the application context
    audiovideo = (AVApplication) getApplication();

    audiovideo.httpCommand(Commands.GET_COUNTIES, null);
  }

  @Override
  protected void onResume() {
    super.onResume();

    showCounties();
  }

  public void showCounties() {
    Log.d(LOG_TAG, TAG + "refreshItemsList();");

    // Get a cursor with all item updates
    cursor = audiovideo.getLocationDB().getCounties();
    startManagingCursor(cursor);

    // Setup the adapter
    adapter = new SimpleCursorAdapter(this, R.layout.county_listview_item, cursor, FROM, TO);

    listItems.setAdapter(adapter);
    listItems.setOnItemClickListener(new OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
        int countyID = cursor.getInt(cursor.getColumnIndex(LocationDB.C_ID));
        String countyName = cursor.getString(cursor.getColumnIndex(LocationDB.C_NAME));
        String foo = String.format(TAG + "Clicked ID #%d (%s)", countyID, countyName);
        Log.i(LOG_TAG, foo);

        // Show the item in a new activity
        Intent apan = new Intent(audiovideo, MunicipalBrowser.class);
        apan.putExtra("countyID", countyID);
        startActivity(apan);
      }
    });
  } // refreshItemsList
}

即:这将打开一个列表视图,并用我所在地区周围的一堆县名填充它。单击一个县时,会启动另一个活动(具有几乎相同的代码),显示该县的市政当局。

该代码大部分都有效。 LogView 中时不时会弹出这些行(每个列表视图单元格一组):

10-11 09:28:06.601: INFO/dalvikvm(244): Uncaught exception thrown by finalizer (will be discarded):
10-11 09:28:06.641: INFO/dalvikvm(244): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44c7e808 on null that has not been deactivated \

或关闭 10-11 09:28:06.651:信息/dalvikvm(244):在 android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596) 10-11 09:28:06.651: INFO/dalvikvm(244): at dalvik.system.NativeStart.run(Native Method)

我不明白为什么我得到这些,但由于模拟器没有崩溃,所以我没有太麻烦了。

现在出现严重错误:当我的列表视图启动并且我在一段时间内(可能 5 分钟)没有单击任何单元格,然后单击时,模拟器严重崩溃并在 LogCat 中输出此内容:

10-11 11:45:22.591: ERROR/AndroidRuntime(255): Uncaught handler: thread main exiting due to uncaught exception
10-11 11:45:22.682: ERROR/AndroidRuntime(255): java.lang.RuntimeException: Unable to start activity ComponentInfo{se.ribit.bb/se.ribit.bb.TownBrowser}: android.database.sqlite.SQLiteException: Unable to close due to unfinalised statements
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.app.ActivityThread.access$2200(ActivityThread.java:119)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.os.Looper.loop(Looper.java:123)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.app.ActivityThread.main(ActivityThread.java:4363)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at java.lang.reflect.Method.invokeNative(Native Method)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at java.lang.reflect.Method.invoke(Method.java:521)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at dalvik.system.NativeStart.main(Native Method)
10-11 11:45:22.682: ERROR/AndroidRuntime(255): Caused by: android.database.sqlite.SQLiteException: Unable to close due to unfinalised statements
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.database.sqlite.SQLiteDatabase.dbclose(Native Method)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.database.sqlite.SQLiteDatabase.onAllReferencesReleased(SQLiteDatabase.java:254)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.database.sqlite.SQLiteClosable.releaseReference(SQLiteClosable.java:42)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.database.sqlite.SQLiteProgram.onAllReferencesReleasedFromContainer(SQLiteProgram.java:76)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.database.sqlite.SQLiteDatabase.closeClosable(SQLiteDatabase.java:799)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.database.sqlite.SQLiteDatabase.close(SQLiteDatabase.java:786)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at se.ribit.bb.LocationDB.updateTowns(LocationDB.java:291)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at se.ribit.bb.AVApplication.httpCommand(AVApplication.java:217)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at se.ribit.bb.TownBrowser.onCreate(TownBrowser.java:44)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     ... 11 more

任何人都可以告诉我这是怎么回事?

Android-newbie playing around with a SimpleCursorAdapter and I've run into a few problems that I'm unable to solve.

This is the code (imports omitted):

package se.ribit.bb;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class CountyBrowser extends Activity {
  private AVApplication audiovideo;
  private final String LOG_TAG = AVApplication.LOG_TAG;
  private final String TAG = "=== " + CountyBrowser.class.getSimpleName() + ": ";

  static final String[] FROM = { LocationDB.C_NAME};
  static final int[]    TO   = { R.id.locationName };

  //  DB dbHelper;
  private Cursor cursor;
  private ListView listItems;
  private SimpleCursorAdapter adapter;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.d(LOG_TAG, TAG + "onCreate");

    setContentView(R.layout.county_main_view);

    // View for the adapter 
    listItems = (ListView) findViewById(R.id.county_listview);

    // Get the application context
    audiovideo = (AVApplication) getApplication();

    audiovideo.httpCommand(Commands.GET_COUNTIES, null);
  }

  @Override
  protected void onResume() {
    super.onResume();

    showCounties();
  }

  public void showCounties() {
    Log.d(LOG_TAG, TAG + "refreshItemsList();");

    // Get a cursor with all item updates
    cursor = audiovideo.getLocationDB().getCounties();
    startManagingCursor(cursor);

    // Setup the adapter
    adapter = new SimpleCursorAdapter(this, R.layout.county_listview_item, cursor, FROM, TO);

    listItems.setAdapter(adapter);
    listItems.setOnItemClickListener(new OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
        int countyID = cursor.getInt(cursor.getColumnIndex(LocationDB.C_ID));
        String countyName = cursor.getString(cursor.getColumnIndex(LocationDB.C_NAME));
        String foo = String.format(TAG + "Clicked ID #%d (%s)", countyID, countyName);
        Log.i(LOG_TAG, foo);

        // Show the item in a new activity
        Intent apan = new Intent(audiovideo, MunicipalBrowser.class);
        apan.putExtra("countyID", countyID);
        startActivity(apan);
      }
    });
  } // refreshItemsList
}

I.e: This opens a listview and fills it with a bunch of county-names around my area. When clicking a county, another activity (with almost identical code) is launched, showing the municipals in the county.

The code works, mostly. Every now and then these lines pops up in LogView (one set for each listview-cell):

10-11 09:28:06.601: INFO/dalvikvm(244): Uncaught exception thrown by finalizer (will be discarded):
10-11 09:28:06.641: INFO/dalvikvm(244): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@44c7e808 on null that has not been deactivated \

or closed
10-11 09:28:06.651: INFO/dalvikvm(244): at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
10-11 09:28:06.651: INFO/dalvikvm(244): at dalvik.system.NativeStart.run(Native Method)

I don't understand why I get these, but since the emulator doesn't crash I didn't bother too much.

Now for the critical error: When my listview is launched and I don't click any of the cells for some amount of time (maybe 5 minutes), and then click, the emulator crashes hard and outputs this in LogCat:

10-11 11:45:22.591: ERROR/AndroidRuntime(255): Uncaught handler: thread main exiting due to uncaught exception
10-11 11:45:22.682: ERROR/AndroidRuntime(255): java.lang.RuntimeException: Unable to start activity ComponentInfo{se.ribit.bb/se.ribit.bb.TownBrowser}: android.database.sqlite.SQLiteException: Unable to close due to unfinalised statements
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.app.ActivityThread.access$2200(ActivityThread.java:119)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.os.Looper.loop(Looper.java:123)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.app.ActivityThread.main(ActivityThread.java:4363)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at java.lang.reflect.Method.invokeNative(Native Method)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at java.lang.reflect.Method.invoke(Method.java:521)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at dalvik.system.NativeStart.main(Native Method)
10-11 11:45:22.682: ERROR/AndroidRuntime(255): Caused by: android.database.sqlite.SQLiteException: Unable to close due to unfinalised statements
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.database.sqlite.SQLiteDatabase.dbclose(Native Method)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.database.sqlite.SQLiteDatabase.onAllReferencesReleased(SQLiteDatabase.java:254)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.database.sqlite.SQLiteClosable.releaseReference(SQLiteClosable.java:42)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.database.sqlite.SQLiteProgram.onAllReferencesReleasedFromContainer(SQLiteProgram.java:76)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.database.sqlite.SQLiteDatabase.closeClosable(SQLiteDatabase.java:799)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.database.sqlite.SQLiteDatabase.close(SQLiteDatabase.java:786)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at se.ribit.bb.LocationDB.updateTowns(LocationDB.java:291)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at se.ribit.bb.AVApplication.httpCommand(AVApplication.java:217)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at se.ribit.bb.TownBrowser.onCreate(TownBrowser.java:44)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
10-11 11:45:22.682: ERROR/AndroidRuntime(255):     ... 11 more

Can anyone tell me what's going on here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

酒浓于脸红 2024-12-16 02:55:36

您是否在 OnDestroy 方法中使用 释放了 Cursor

stopManagingCursor(c);

哦,你应该使用 CursorLoader,startManagingCursor() 已弃用。

Loader API 通过兼容性包提供给旧设备,请参阅:http://mobile.tutsplus.com/tutorials/android/android-compatibility-working-with-fragments/

Do your release the Cursor in your OnDestroy method with

stopManagingCursor(c);

?

oh and your should use the CursorLoader, startManagingCursor() is deprecated.

The Loader API comes to old devices with the compatiblity Package, See this: http://mobile.tutsplus.com/tutorials/android/android-compatibility-working-with-fragments/

烟若柳尘 2024-12-16 02:55:36

不看代码很难知道,但您可能在关闭游标之前关闭数据库: SQLite Exception in android

这是错误所在,因此您应该检查那里:在 se.ribit.bb.LocationDB.updateTowns(LocationDB.java:291)

It's hard to know without seeing code, but you are probably closing the database before closing the cursor: SQLite Exception in android

This is where the error is, so you should inspect there: at se.ribit.bb.LocationDB.updateTowns(LocationDB.java:291)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文