【问题标题】:Where to close Close cursor and database object in Activity without any exceptionActivity 中关闭游标和数据库对象的位置没有任何异常
【发布时间】:2014-04-01 16:39:53
【问题描述】:

在我的应用程序中,有很多数据库操作,所以我创建了很多游标来检索数据,并且异步任务中使用的游标也很少。现在我的问题是在哪里关闭游标和数据库。

当我在异步操作后关闭onCreate 中的游标时,我得到Null Pointer Exception,如果我在onPause 中关闭,我仍然得到Null pointer exception,所以我已经关闭了@987654326 中的游标和数据库@。

现在我很困惑这种方法是否正确。我想了解在活动中关闭游标和数据库而不影响数据库操作的最佳方法。

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.stockdetail);
        //Helptext.setVisibility(View.INVISIBLE);
        Declerations();

        d=Database.getInstance(getApplicationContext()).getWritableDatabase();



        new popdailydata().execute();
// Above is async task so I have closed after above statement, but if I close cursor getting Null pointer exception

protected void onDestroy() {
        // TODO Auto-generated method stub
    super.onDestroy();
    selectdate.close();
    Database.getInstance(getApplicationContext()).close();

    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        //selectdate.close(); --- At this point also I am getting nullpointer exception
        Database.getInstance(getApplicationContext()).close();
    }

04-01 17:03:48.045: D/dalvikvm(1288): Late-enabling CheckJNI
04-01 17:03:50.021: D/libEGL(1288): loaded /system/lib/egl/libEGL_genymotion.so
04-01 17:03:50.113: D/(1288): HostConnection::get() New Host Connection established 0xb90bb5c8, tid 1288
04-01 17:03:50.177: D/libEGL(1288): loaded /system/lib/egl/libGLESv1_CM_genymotion.so
04-01 17:03:50.181: D/libEGL(1288): loaded /system/lib/egl/libGLESv2_genymotion.so
04-01 17:03:50.773: W/EGL_genymotion(1288): eglSurfaceAttrib not implemented
04-01 17:03:50.797: E/OpenGLRenderer(1288): Getting MAX_TEXTURE_SIZE from GradienCache
04-01 17:03:50.861: E/OpenGLRenderer(1288): Getting MAX_TEXTURE_SIZE from Caches::initConstraints()
04-01 17:03:50.865: D/OpenGLRenderer(1288): Enabling debug mode 0
04-01 17:03:54.645: D/dalvikvm(1288): GC_FOR_ALLOC freed 102K, 1% free 16948K/17072K, paused 89ms, total 96ms
04-01 17:03:54.709: D/AndroidRuntime(1288): Shutting down VM
04-01 17:03:54.725: W/dalvikvm(1288): threadid=1: thread exiting with uncaught exception (group=0xa4c45648)
04-01 17:03:54.745: E/AndroidRuntime(1288): FATAL EXCEPTION: main
04-01 17:03:54.745: E/AndroidRuntime(1288): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.portfoliomanager/com.example.StockDirector.stockmanager}: java.lang.NullPointerException
04-01 17:03:54.745: E/AndroidRuntime(1288):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
04-01 17:03:54.745: E/AndroidRuntime(1288):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
04-01 17:03:54.745: E/AndroidRuntime(1288):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
04-01 17:03:54.745: E/AndroidRuntime(1288):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
04-01 17:03:54.745: E/AndroidRuntime(1288):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-01 17:03:54.745: E/AndroidRuntime(1288):     at android.os.Looper.loop(Looper.java:137)
04-01 17:03:54.745: E/AndroidRuntime(1288):     at android.app.ActivityThread.main(ActivityThread.java:5103)
04-01 17:03:54.745: E/AndroidRuntime(1288):     at java.lang.reflect.Method.invokeNative(Native Method)
04-01 17:03:54.745: E/AndroidRuntime(1288):     at java.lang.reflect.Method.invoke(Method.java:525)
04-01 17:03:54.745: E/AndroidRuntime(1288):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
04-01 17:03:54.745: E/AndroidRuntime(1288):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
04-01 17:03:54.745: E/AndroidRuntime(1288):     at dalvik.system.NativeStart.main(Native Method)
04-01 17:03:54.745: E/AndroidRuntime(1288): Caused by: java.lang.NullPointerException
04-01 17:03:54.745: E/AndroidRuntime(1288):     at com.example.StockDirector.stockmanager.onCreate(stockmanager.java:81)
04-01 17:03:54.745: E/AndroidRuntime(1288):     at android.app.Activity.performCreate(Activity.java:5133)
04-01 17:03:54.745: E/AndroidRuntime(1288):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
04-01 17:03:54.745: E/AndroidRuntime(1288):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
04-01 17:03:54.745: E/AndroidRuntime(1288):     ... 11 more
04-01 17:03:57.889: I/Process(1288): Sending signal. PID: 1288 SIG: 9

【问题讨论】:

  • 您没有显示您使用Cursor 的内容,也没有显示显示 NPE 的 logcat 输出。 Cursor 必须在任何需要它的应用程序组件的生命周期内保持打开状态。例如,如果您将其与SimpleCursorAdapter 一起使用来填充ListView,则在不再使用ListViewSimpleCursorAdapter 之前,您无法关闭Cursor
  • @Squonk 感谢您的回答,并为没有提供 logcat 表示歉意...用 logcat 编辑了我的问题。请指教
  • 这仍然不能真正解释您如何使用Cursor。您表明您正在调用 AsyncTask,但不是 AsyncTask 对检索到的数据所做的事情。
  • ​​​​​​​​​​​​​​@g2o:请记住:Tiny, trivial edits are discouraged - try to make the post significantly better when you edit, correcting all problems that you observe. 所以不要将cusor替换为cursor修复每个问题都像我做的那样。

标签: android android-sqlite android-cursoradapter


【解决方案1】:

对于 android 数据库操作的整体操作,这里是使用内容提供程序的重要信息来源: http://www.vogella.com/tutorials/AndroidSQLite/article.html

这是一个如何实现 LoaderManager 的示例。您可以在此处找到各种示例:http://developer.android.com/reference/android/app/LoaderManager.html

对于一个基本的实现思路,它应该是这样的:

public class MainActivity extends Activity implements LoaderManager.LoaderCallbacks<Cursor> {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    return new CursorLoader(this,
            ObjectEntity.URI,   // Database uri
            new String[]{"id"}, // Columns to select
            "id=?",               // 'where' field
            new String[]{"3"},  // Values for 'where' '?' field
            null);
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    // Do anything you want here with the cursor
}

@Override
public void onLoaderReset(Loader<Cursor> loader) {

}

}

【讨论】:

  • 感谢您的回复...将通过链接。
【解决方案2】:

您应该尽快关闭数据库/光标连接,这意味着一旦您从中提取数据,您应该关闭所有内容,以免锁定数据库。

保持数据库连接是不好的做法,尤其是对于多线程应用程序

【讨论】:

  • 感谢您的回复,但这是我的问题,当我在任何 db 操作后立即关闭时,它会抛出我 Null Pointer Exception。在我的问题中,如果我在new popdailydata().execute(); 之后关闭它会给我一个例外
  • @tyczj :您的答案并不完全正确。如果要与AdapterAdapterView 一起使用,Cursor 必须保持打开状态。此外,如果您使用SQLiteOpenHelper,则显式关闭数据库可能是有害的 - 检查源代码。
  • @Siva 如果你得到 null,这意味着 Database.getInstance(getApplicationContext()).getWritableDatabase() 正在返回 null。在您启动异步任务后立即关闭也不好,因为应用程序在异步任务完成之前不会暂停,这会破坏异步任务的目的
  • @Squonk 是的,这是过去需要打开光标的时间,但如果他只是在提取数据,那么您需要将其关闭。从来没有明确说过,所以我认为它只是在提取数据
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-02
  • 1970-01-01
  • 2011-06-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多