Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/183.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android sqlite日志报告和db.close()_Java_Android_Sqlite - Fatal编程技术网

Java Android sqlite日志报告和db.close()

Java Android sqlite日志报告和db.close(),java,android,sqlite,Java,Android,Sqlite,日志报告数据库或游标未关闭。我基本上有一个带有自定义surfaceview的活动,并使用处理程序向该活动报告。当我收到消息时,我会显示一个alertdialog并更新数据库 private Handler handler = new Handler() { public void handleMessage(Message msg) { switch(msg.what) { case 1: dh.open();

日志报告数据库或游标未关闭。我基本上有一个带有自定义surfaceview的活动,并使用处理程序向该活动报告。当我收到消息时,我会显示一个alertdialog并更新数据库

private Handler handler = new Handler() {
    public void handleMessage(Message msg) {
        switch(msg.what) {
        case 1:
            dh.open();
            dh.updateEvent("id", "name", "someone");
            dh.close();
            successAlert.show();
            break;
        case 2:
            failAlert.show();
            break;
        }
    }
};
以前我没有“dh.close()”,这就是日志报告的数据库/游标未关闭的时候。但自从我在中添加这一点以来,它需要很长时间才能完成。一旦我得到这个信息,系统就好像挂了。是我做错了什么,还是通常要花这么长时间。我还尝试使用带有finally的try块来关闭db

编辑:

}

扩展的SQLiteOpenHelper:

public class Database extends SQLiteOpenHelper {

private static final String DATABASE_NAME = "events.db";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NAME = "stateTable";
private static final String ID = "id";
private static final String NAME = "name";
private static final String OTHER = "other";
private static final String DATABASE_CREATE = "CREATE TABLE stateTable (id INT, name TEXT, other INT)";
private static final String DATABASE_UPGRADE = "DROP TABLE IF EXISTS table";

public Database(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
    // TODO Auto-generated constructor stub
}

@Override
public void onCreate(SQLiteDatabase db) {
    // TODO Auto-generated method stub
    db.execSQL(DATABASE_CREATE);
    // added initial values
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // TODO Auto-generated method stub
    db.execSQL(DATABASE_UPGRADE);
    onCreate(db);
}
}

我认为这里您应该关闭数据库句柄
db
,而不是
dbHelper

同样在您的
checkState
方法中:

public boolean checkState(int id) {
    db = dbHelper.getReadableDatabase();
    Cursor cursor = db.query("stateTable", null, null, null, null, null, null);
    cursor.moveToPosition(id - 1);
    int i = cursor.getInt(2);
    android.util.Log.d("semajhan", ": " + i);
    if (i == 1) {
        return true;
    } else {
        return false;
    }
}
您可能希望关闭光标,如下所示:

int i = cursor.getInt(2);
cursor.close();
android.util.Log.d("semajhan", ": " + i);

我想知道光标未关闭的根本问题是否与中的相同:活动需要有一个关闭DatabaseHelper的
onDestroy
方法。(我现在所能说的是,你没有显示
ondestory
方法,但这显然只是你代码的一部分。)我也写了关于这个问题的博客

您还写道:“但是自从我添加[
dh.close()
]以来,它需要很长时间才能完成。”您是否对数据库进行了大量写入?也许您需要使用事务定期刷新这些写入。如果您只是从数据库中读取,那么我不知道为什么
close
调用需要很长时间才能完成。但是没有看到更多的代码,这些只是猜测

EDIT:'s关于在调用
dbHelper()之前调用
db.close()
的建议值得遵循。但是,您需要检查db是否为null。这将
检查状态更改为:

public boolean checkState(int id) {
    if (db != null) {
        db.close();
    }
    db = dbHelper.getReadableDatabase();
    // ... etc ....
如果这是真正的问题,请接受切尼森的答案,而不是我的

(上面的编辑不正确;我应该知道得更清楚!请参见下文。) 编辑1:我不确定您为什么要用这种方法打开数据库。假设调用了
DatabaseHelper.open
方法,则具有可读的和可写的数据库句柄<代码>检查状态
不需要重新打开它来执行读取


编辑2:但是,几乎总是返回从
SQLiteOpenHelper.getWriteableDatabase
返回的相同数据库句柄。不需要显式关闭该数据库句柄;SQLiteOpenHelper将为您关闭它。您确实需要确保在活动被销毁时调用
SQLiteOpenHelper.close

第一次调用
SQLiteOpenHelper
实例的
getReadableDatabase
getwriteabledatabase
需要很长时间才能完成。每次需要查询数据库时,不应创建新的
数据库
对象(您的
SQLiteOpenHelper
实例)。尝试在
DatabaseHelper
中使用相同的
数据库
实例

使用
SQLiteOpenHelper
时,您不希望关闭
SQLiteDatabase
对象的
SQLiteOpenHelper
,因为它是共享的;i、 e.
getWritableDatabase
始终返回相同的
SQLiteDatabase
对象

请注意,您的
checkState
方法泄漏了一个光标。为了防止光标泄漏,我总是在获得光标后使用
try
-
finally
。例如:

    db = dbHelper.getReadableDatabase();
    Cursor cursor = db.query("stateTable", null, null, null, null, null, null);
    try {
        cursor.moveToPosition(id - 1);
        int i = cursor.getInt(2);
        android.util.Log.d("semajhan", ": " + i);
        if (i == 1) {
                return true;
        } else {
                return false;
        }
    } finally {
        cursor.close();
    }

处理程序代码看起来不错,但是我们看不到您的
dh
是如何编码的,所以很难说是什么导致了延迟。我们将在一秒钟内发布更多代码。好的,数据库编码在哪里?除非它是adk的一部分,我在任何地方都看不到它…数据库是SQLiteOpenHelper扩展类。问题是,我已经做了所有这些。在我以前的代码中,我使用db close的句柄而不是dbHelper。在我的checkState方法中,我还调用了cursor.close()。但这导致了泄漏。一旦我从关闭db切换到dbHelper,泄漏就消失了,但我的日志中出现了一些奇怪的错误。只要一堆数字,给我一个百分比:user=72%kernel=28%之类的
,首先尝试关闭数据库:
db.close();db=dbHelper.getReadableDatabase()。在此之后,没有其他想法:)首先关闭db会导致强制关闭=[查看DDMS下的LogCat,看看是否有任何堆栈跟踪可以帮助我们调试找到的DDMS,但在LogCat中,我没有看到任何与“堆栈跟踪”相关的内容。我现在正在查看你的博客和链接。我只写了一行3列:一个INT、TEXT和另一个INT。这对SQL来说是非常新的,但我只写1行3列应该非常快。所以基本上,当我创建SQLiteOpenHelper的实例时,我已经“打开”了用于读写的数据库?对于读,我不需要显式调用db.getReadableDatabase()?@semajhan:不完全是。在你调用
db.getWriteableDatabase
db.getReadableDatabase
之前,数据库是不会打开的。但是调用
db.getWriteableDatabase
可以让你读取和写入数据库。因此我认为你在调用之后不需要调用
db.getReadableDatabase
ode>db.getWriteableDatabase
。啊,这很有道理。因此,如果我已经调用了getWriteableDatabase(),我就不需要调用getReadableDatabase()。但假设我在getWriteableDatabase()之后调用getReadableDatabase(),这是否意味着我正在打开数据库两次,可能会导致泄漏?@semajhan:不,它不会导致泄漏。
SQLiteOpenHelper
保留对数据库h的引用
int i = cursor.getInt(2);
cursor.close();
android.util.Log.d("semajhan", ": " + i);
public boolean checkState(int id) {
    if (db != null) {
        db.close();
    }
    db = dbHelper.getReadableDatabase();
    // ... etc ....
    db = dbHelper.getReadableDatabase();
    Cursor cursor = db.query("stateTable", null, null, null, null, null, null);
    try {
        cursor.moveToPosition(id - 1);
        int i = cursor.getInt(2);
        android.util.Log.d("semajhan", ": " + i);
        if (i == 1) {
                return true;
        } else {
                return false;
        }
    } finally {
        cursor.close();
    }