永发信息网

androidcursor具体逻辑由谁执行

答案:2  悬赏:20  手机版
解决时间 2021-12-20 15:35
  • 提问者网友:温旧梦泪无声
  • 2021-12-19 15:00
请问cursor.moveTonext这些方法的具体逻辑在哪
最佳答案
  • 五星知识达人网友:街头电车
  • 2021-12-19 16:14
本文介绍如何在 Android 检测 Cursor 泄漏的原理以及使用方法,还指出几种常见的出错示例。有一些泄漏在代码中难以察觉,但程序长时间运行后必然会出现异常。同时该方法同样适合于其他需要检测资源泄露的情况。

最近发现某蔬菜手机连接程序在查询媒体存储(MediaProvider)数据库时出现严重 Cursor 泄漏现象,运行一段时间后会导致系统中所有使用到该数据库的程序无法使用。另外在工作中也常发现有些应用有 Cursor 泄漏现象,由于需要长时间运行才会出现异常,所以有的此类 bug 很长时间都没被发现。

但是一旦 Cursor 泄漏累计到一定数目(通常为数百个)必然会出现无法查询数据库的情况,只有等数据库服务所在进程死掉重启才能恢复正常。通常的出错信息如下,指出某 pid 的程序打开了 866 个 Cursor 没有关闭,导致了 exception:

复制代码代码如下:

3634 3644 E JavaBinder: *** Uncaught remote exception! (Exceptions are not yet supported across processes.)
3634 3644 E JavaBinder: android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=866 (# cursors opened by pid 1565=866)
3634 3644 E JavaBinder: at android.database.CursorWindow.(CursorWindow.java:104)
3634 3644 E JavaBinder: at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
3634 3644 E JavaBinder: at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:147)
3634 3644 E JavaBinder: at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:141)
3634 3644 E JavaBinder: at android.database.CursorToBulkCursorAdaptor.getBulkCursorDescriptor(CursorToBulkCursorAdaptor.java:143)
3634 3644 E JavaBinder: at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:118)
3634 3644 E JavaBinder: at android.os.Binder.execTransact(Binder.java:367)
3634 3644 E JavaBinder: at dalvik.system.NativeStart.run(Native Method)
全部回答
  • 1楼网友:枭雄戏美人
  • 2021-12-19 16:28
简单可理解为数据链指针 使用过 sqlite 数据库的童鞋对 cursor 应该不陌生,如果你是搞.net 开发你大可以把cursor理解成 ado.net 中的数据集合相当于datareader。今天特地将它单独拿出来谈,加深自己和大家对android 中使用 cursor 的理解。 关于 cursor 在你理解和使用 android cursor 的时候你必须先知道关于 cursor 的几件事情: cursor 是每行的集合。 使用 movetofirst() 定位第一行。 你必须知道每一列的名称。 你必须知道每一列的数据类型。 cursor 是一个随机的数据源。 所有的数据都是通过下标取得。 关于 cursor 的重要方法: close() 关闭游标,释放资源 copystringtobuffer(int columnindex, chararraybuffer buffer) 在缓冲区中检索请求的列的文本,将将其存储 getcolumncount() 返回所有列的总数 getcolumnindex(string columnname) 返回指定列的名称,如果不存在返回-1 getcolumnindexorthrow(string columnname) 从零开始返回指定列名称,如果不存在将抛出illegalargumentexception 异常。 getcolumnname(int columnindex) 从给定的索引返回列名 getcolumnnames() 返回一个字符串数组的列名 getcount() 返回cursor 中的行数 movetofirst() 移动光标到第一行 movetolast() 移动光标到最后一行 movetonext() 移动光标到下一行 movetoposition(int position) 移动光标到一个绝对的位置 movetoprevious() 移动光标到上一行 下面来看看一小段代码: if (cur.movetofirst() == false) { //为空的cursor return; } 访问 cursor 的下标获得其中的数据 int namecolumnindex = cur.getcolumnindex(people.name); string name = cur.getstring(namecolumnindex); 现在让我们看看如何循环 cursor 取出我们需要的数据 while(cur.movetonext()) { //光标移动成功 //把数据取出 } 当cur.movetonext() 为假时将跳出循环,即 cursor 数据循环完毕。 如果你喜欢用 for 循环而不想用while 循环可以使用google 提供的几下方法: isbeforefirst() 返回游标是否指向之前第一行的位置 isafterlast() 返回游标是否指向第最后一行的位置 isclosed() 如果返回 true 即表示该游戏标己关闭 有了以上的方法,可以如此取出数据 for(cur.movetofirst();!cur.isafterlast();cur.movetonext()) { int namecolumn = cur.getcolumnindex(people.name); int phonecolumn = cur.getcolumnindex(people.number); string name = cur.getstring(namecolumn); string phonenumber = cur.getstring(phonecolumn); } tip:在android 查询数据是通过cursor 类来实现的。当我们使用 sqlitedatabase.query()方法时,就会得到cursor对象, cursor所指向的就是每一条数据。结合ado.net 的知识可能好理解一点。 cursor 位于 android.database.cursor类,可见出它的设计是基于数据库服务产生的。
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯