Android - 从服务查询数据库

Android - Querying the database from service

我正在开发一个应用程序,其中 info 存储在 database 中。我也在 my service 中得到 new info 但在将它们提交到我的数据库之前,我想 check if the new info I have already exists in the database or not. 为此,我正在从我的服务中查询数据库以获取该特定信息,并且我得到 android.database.CursorWindowAllocationException.. 我用谷歌搜索并找到 this answer。据此,我收到该错误是因为我正在从我的服务中查询数据库。

对此有任何解决方法吗?

查询数据库的代码

public String getLogData() {
    String[] coloumns = { KEY_NETWORK_INFO };
    Cursor c = ourDatabase.query(LOG_TABLE_NAME, coloumns, null, null,
            null, null, null);
    String result = "";
    int iNetworkInfo = c.getColumnIndex(KEY_NETWORK_INFO);
    for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
        result = result + c.getString(iNetworkInfo) + ", ";
    }
    return result;
}

LOGCAT:

    01-21 13:43:00.633: E/AndroidRuntime(14871): android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=762 (# cursors opened by this proc=762)
01-21 13:43:00.633: E/AndroidRuntime(14871):    at android.database.CursorWindow.<init>(CursorWindow.java:108)
01-21 13:43:00.633: E/AndroidRuntime(14871):    at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
01-21 13:43:00.633: E/AndroidRuntime(14871):    at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:139)
01-21 13:43:00.633: E/AndroidRuntime(14871):    at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
01-21 13:43:00.633: E/AndroidRuntime(14871):    at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:197)
01-21 13:43:00.633: E/AndroidRuntime(14871):    at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:237)
01-21 13:43:00.633: E/AndroidRuntime(14871):    at com.iqra.adeel.newfyp.part1.AreaDatabase.getLogData(AreaDatabase.java:153)
01-21 13:43:00.633: E/AndroidRuntime(14871):    at com.iqra.adeel.newfyp.part1.MyService$MyPhoneStateListener.onSignalStrengthsChanged(MyService.java:102)
01-21 13:43:00.633: E/AndroidRuntime(14871):    at android.telephony.PhoneStateListener.handleMessage(PhoneStateListener.java:301)
01-21 13:43:00.633: E/AndroidRuntime(14871):    at android.os.Handler.dispatchMessage(Handler.java:102)
01-21 13:43:00.633: E/AndroidRuntime(14871):    at android.os.Looper.loop(Looper.java:135)
01-21 13:43:00.633: E/AndroidRuntime(14871):    at android.app.ActivityThread.main(ActivityThread.java:5223)
01-21 13:43:00.633: E/AndroidRuntime(14871):    at java.lang.reflect.Method.invoke(Native Method)
01-21 13:43:00.633: E/AndroidRuntime(14871):    at java.lang.reflect.Method.invoke(Method.java:372)
01-21 13:43:00.633: E/AndroidRuntime(14871):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
01-21 13:43:00.633: E/AndroidRuntime(14871):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

我认为出现此问题是因为您在使用完它后没有close your Cursor object. You should close它在服务中,并且问题不会持续存在。

此错误几乎总是由于游标完成后未关闭 with.And 您从服务中调用 getLogData 因此,如果游标未关闭并且应用程序继续打开新游标,则会出现此错误很有可能发生。see here

因此在您的代码中关闭光标为

 if (c != null)
     c.close();

在返回结果之前,即将 getLogData 方法重写为

public String getLogData() {
    String[] coloumns = { KEY_NETWORK_INFO };
    Cursor c = ourDatabase.query(LOG_TABLE_NAME, coloumns, null, null,
            null, null, null);
    String result = "";
    int iNetworkInfo = c.getColumnIndex(KEY_NETWORK_INFO);
    for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
        result = result + c.getString(iNetworkInfo) + ", ";
    }
    if (c != null)
     c.close();
    return result;
}

这是因为游标的任务完成后游标没有关闭。 每当您打开游标时,游标都需要内存,如果您不关闭它,它将占用更多内存。 如果你检查错误

"Open Cursors=762 (# cursors opened by this proc=762)"

表示您的代码中打开的游标是 762 尽管如此,它还是需要记忆的。 所以在不需要时关闭游标。

就像你的情况一样,特别是你作为代码发布的方法,在循环获取数据后关闭它

if (c != null)
     c.close();