【问题标题】:Iterate Through Cursor, moveToNext() Does Not Appear To Work遍历光标,moveToNext() 似乎不起作用
【发布时间】:2013-07-15 20:51:37
【问题描述】:

我遇到了一些问题。我正在尝试遍历游标以提取所需的数据。但是moveToNext() 方法似乎没有将光标移过第一个位置。它将移动到第一行结果没问题,但似乎它不会越过第一行并且每次都返回true。导致无限循环。这是我的代码:

此方法将新项目添加到数据库中:

public List<Items> getAllItems() {
    SQLiteDatabase db = getWritableDatabase();
    DatabaseParser parser = new DatabaseParser();

    Cursor result = db.rawQuery("SELECT * FROM " + TableName.ITEMS.getName(), null);
    List<Trip> items = parser.cursorToListOfItems(result);

    Cursor moreResults = db.rawQuery("SELECT * FROM " + TableName.MORE_ITEMS.getName(), null);
    List<MoreItems> moreItems = parser.cursorToListOfMoreItems(moreResults);

    items = parser.combineListOfItemsWithListOfMoreItems(items, moreItems);

    db.close();
    result.close();

    return items;
}


这是cursorToListOfItems() 方法将数据从游标中拉出并放入ArrayList

List<Items> cursorToListOfItems(Cursor data) {
    List<Items> items = new ArrayList<Items>();
    Items item = null;

    if (data.moveToFirst()) {
        do {
            item = new Items(DataFactory.getDatabaseItemsData(data));
            items.add(trip);
        }
        while (data.moveToNext());
    }

    return items;
}



现在我的问题是,在 cursorToListOfItems() 中,对 moveToNext() 的调用总是返回 true,这会导致我的应用程序崩溃。

我尝试过的事情

  1. 我尝试了不同的方式来遍历光标而没有改变。

  2. 我也删除了应用程序文件并卸载然后重新安装了应用程序,但我仍然遇到同样的问题。

  3. 我还连接了调试器来查看游标,我可以看到指示它在哪一行的标记从01,表明它成功地转到第一行,然后是第二行。但此后每次循环执行时,位置都保持在 1。表示它永远不会越过第二行以查找是否还有更多数据要执行,并且只返回 true 以启动无限循环。

我现在遇到了这堵砖墙。非常感谢任何能引导我找到解决方案的帮助、答案或建议。

编辑
我检查了日志,没有抛出异常。只记录我最终得到的 ANR。但为了安全起见,我会在此处发布日志:

07-15 16:00:02.368 60-309/system_process I/ActivityManager: 开始: Intent { cmp=com.eyephonegrourp.itruckit/.MainActivity } 来自 pid 441
07-15 16:00:02.518 441-441/com.eyephonegrourp.itruckit D/dalvikvm: GC_EXTERNAL_ALLOC 释放 27K, 52% 释放 2589K/5379K, 外部 3399K/3716K, 暂停 34ms
07-15 16:00:04.007 441-443/com.eyephonegrourp.itruckit D/dalvikvm:GC_CONCURRENT 释放 701K,50% 释放 3421K/6727K,外部 3842K/4311K,暂停 3ms+3ms
07-15 16:00:05.127 441-443/com.eyephonegrourp.itruckit D/dalvikvm:GC_CONCURRENT 释放 698K,44% 释放 4285K/7623K,外部 3842K/4311K,暂停 3ms+4ms
07-15 16:00:06.448 441-443/com.eyephonegrourp.itruckit D/dalvikvm:GC_CONCURRENT 释放 866K,40% 释放 5298K/8775K,外部 3842K/4311K,暂停 3ms+4ms
07-15 16:00:07.468 60-90/system_process I/InputDispatcher:应用程序没有响应:窗口{406fa4b8 com.eyephonegrourp.itruckit/com.eyephonegrourp.itruckit.SplashActivity paused=true}。事件发生后 5005.0 毫秒,等待开始后 5004.8 毫秒
07-15 16:00:07.468 60-90/system_process I/WindowManager:输入事件调度超时发送到 com.eyephonegrourp.itruckit/com.eyephonegrourp.itruckit.SplashActivity
07-15 16:00:07.503 441-444/com.eyephonegrourp.itruckit I/dalvikvm: threadid=4: 对信号 3 做出反应
07-15 16:00:07.557 441-444/com.eyephonegrourp.itruckit I/dalvikvm:将堆栈跟踪写入“/data/anr/traces.txt”
07-15 16:00:08.498 441-443/com.eyephonegrourp.itruckit D/dalvikvm:GC_CONCURRENT 释放 940K,36% 释放 6405K/9991K,外部 3842K/4311K,暂停 3ms+5ms
07-15 16:00:08.577 60-90/system_process E/ActivityManager: com.eyephonegrourp.itruckit (com.eyephonegrourp.itruckit/.MainActivity) 中的 ANR
原因:keyDispatchingTimedOut
父级:com.eyephonegrourp.itruckit/.SplashActivity
负载:0.36 / 0.27 / 0.14
CPU使用率从47129ms到2463ms前:
4% 60/system_server:3.7% 用户 + 0.2% 内核/故障:1142 次要
1.6% 349/com.android.launcher:1.3% 用户 + 0.3% 内核/故障:3315 次要
0% 40/adbd:0% 用户 + 0% 内核/故障:13 个次要
0% 135/com.android.systemui:0% 用户 + 0% 内核/故障:4 个次要
+0% 439/sh:0% 用户 + 0% 内核
+0% 440/logcat:0% 用户 + 0% 内核
+0% 441/com.eyephonegrourp.itruckit:0% 用户 + 0% 内核
13% 总计:11% 用户 + 1.8% 内核
CPU 使用率从 542ms 到 1077ms 后:
92% 441/com.eyephonegrourp.itruckit:92% 用户 + 0% 内核/故障:207 个次要
71% 441/grourp.itrukit:71% 用户 + 0% 内核
20% 443/GC:20% 用户 + 0% 内核
5.5% 60/system_server:1.8% 用户 + 3.7% 内核/故障:1 个次要
3.7% 90/InputDispatcher:1.8% 用户 + 1.8% 内核
1.8% 61/HeapWorker:0% 用户 + 1.8% 内核
1.8% 73/ActivityManager:1.8% 用户 + 0% 内核
98% 总计:92% 用户 + 5.5% 内核
07-15 16:00:10.187 60-73/system_process W/ActivityManager:强制完成活动 com.eyephonegrourp.itruckit/.MainActivity
07-15 16:00:10.208 60-73/system_process I/ActivityManager: Killing com.eyephonegrourp.itruckit (pid=441): 用户请求
07-15 16:00:10.228 60-126/system_process I/ActivityManager: 进程 com.eyephonegrourp.itruckit (pid 441) 已死亡。
07-15 16:00:10.238 60-90/system_process E/InputDispatcher: 通道 '406fa4b8 com.eyephonegrourp.itruckit/com.eyephonegrourp.itruckit.SplashActivity (server)' ~ 消费者关闭输入通道或发生错误。事件=0x8
07-15 16:00:10.238 60-90/system_process E/InputDispatcher: 频道 '406fa4b8 com.eyephonegrourp.itruckit/com.eyephonegrourp.itruckit.SplashActivity (server)' ~ 频道已不可恢复地损坏,将被处置!
07-15 16:00:10.268 60-307/system_process I/WindowManager: WIN DEATH: Window{406fa4b8 com.eyephonegrourp.itruckit/com.eyephonegrourp.itruckit.SplashActivity paused=true}


编辑 2 这是您请求的日志:

07-15 16:13:19.738 1710-6219/system_process I/ActivityManager:启动活动:Intent { cmp=com.eyephonegrourp.itruckit/.MainActivity } 来自 pid 9583
07-15 16:13:19.908 9583-9583/com.eyephonegrourp.itruckit D/数据库:dbopen():路径 = /data/data/com.eyephonegrourp.itruckit/databases/itruckit,标志 = 6,文件大小 = 11264
07-15 16:13:19.908 9583-9583/com.eyephonegrourp.itruckit D/数据库:dbopen():路径 = /data/data/com.eyephonegrourp.itruckit/databases/itruckit,模式:wal,磁盘可用大小: 2538 M,句柄:0x3496e8
07-15 16:13:23.552 9583-9583/com.eyephonegrourp.itruckit I/log-count: 2
07-15 16:13:23.562 9583-9583/com.eyephonegrourp.itruckit I/log-position: 0
07-15 16:13:23.602 9583-9583/com.eyephonegrourp.itruckit I/log-count: 2
07-15 16:13:23.602 9583-9583/com.eyephonegrourp.itruckit I/log-position: 1
07-15 16:13:23.622 9583-9583/com.eyephonegrourp.itruckit I/log-count: 2
07-15 16:13:23.622 9583-9583/com.eyephonegrourp.itruckit I/log-position: 1
07-15 16:13:23.622 9583-9583/com.eyephonegrourp.itruckit I/log-count: 2
07-15 16:13:23.622 9583-9583/com.eyephonegrourp.itruckit I/log-position: 1
07-15 16:13:23.622 9583-9583/com.eyephonegrourp.itruckit I/log-count: 2
07-15 16:13:23.622 9583-9583/com.eyephonegrourp.itruckit I/log-position: 1
07-15 16:13:23.622 9583-9583/com.eyephonegrourp.itruckit I/log-count: 2
07-15 16:13:23.622 9583-9583/com.eyephonegrourp.itruckit I/log-position: 1
07-15 16:13:23.632 9583-9583/com.eyephonegrourp.itruckit I/log-count: 2
...不断重复...


编辑 3
这是DataFactory.getDatabaseItemsData(data)的代码:

public static final DatabaseHelper.DatabaseTripData getDatabaseTripData(Cursor cursor) {
    if (cursor.moveToFirst()) {
        return createTripData(cursor.getLong(0), cursor.getInt(1), cursor.getInt(2),  
            cursor.getInt(3), cursor.getInt(4), cursor.getString(5), 
            cursor.getString(6), cursor.getLong(7), cursor.getLong(8), 
            cursor.getString(9), cursor.getString(10), cursor.getString(11));
}

return null;
}


createTripData() 所做的只是从游标中获取数据并创建一个包装类来保存它。

【问题讨论】:

  • 发布错误是什么
  • 我为你发布了日志。
  • items.add(trip); trip 是什么?应该是item
  • 将循环更改为 while (data.moveToNext()) { ....},并删除最初的 moveToFirst()。这样就简单多了。
  • 我怀疑你将光标移动到第一行再次 if (cursor.moveToFirst()) 删除此检查。请参阅@CL 答案

标签: android sqlite iterator cursor


【解决方案1】:

您的问题是getDatabaseItemsData 再次调用moveToFirst

您应该更改getDatabaseItemsData,使其假定光标已经定位在有效记录上,即,只需删除moveToFirst 调用。

【讨论】:

    【解决方案2】:

    由于您的操作在 UI 线程中(从 db 读取),您的应用会崩溃,您应该使用 AsyncTask 或 Thread。

    ANR in com.eyephonegrourp.itruckit (com.eyephonegrourp.itruckit/.MainActivity)
    Reason: keyDispatchingTimedOut
    

    ANR 错误:活动无响应。

    【讨论】:

    • 不是很抱歉。我正在访问的表中只有两行,没有理由花费 5 秒来提取 2 行数据。我确实计划在应用程序发布之前将它们移动到不同的线程,但这应该不到 2 毫秒。
    • 也许你有一个 infint 循环,比如“getDatabaseItemsData”调试代码。并检查文件'/data/anr/traces.txt',使用命令“./adb pull path_to_file location_to_save”
    猜你喜欢
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 2011-09-19
    • 2016-11-29
    • 2016-02-01
    相关资源
    最近更新 更多