Android应用程序CursorWindow内存错误

时间:2011-07-22 13:12:56

标签: android web-services

在运行我的应用程序几分钟后,我正在收到“IllegalStateException无法初始化光标窗口”。我的应用程序启动时启动三种不同的服务,每次轮询(每1秒)一个不同的RESTful Web服务。检索/解析结果后,每个服务都有一个ContentProvider,它们会将新数据插入其中。然后,ContentProvider使用setNotificationUri让当前活动知道有新数据可用(如果他们订阅了从该URI获取更新)。

第一个问题,这是轮询RESTful Web服务并将结果传递给感兴趣的活动的正确方法吗?在阅读this question的答案后,似乎ContentProvider是不必要的,因为所有内容都存在于同一个应用程序中。

第二个问题,可能导致IllegalStateException的原因是什么?事实证明没有足够的堆分配CursorWindow(cursorwindow堆分配失败)。我想也许问题是当我查询ContentProvider时(在收到通知后)它在光标中返回了太多结果。活动实际上只需要收到最后一次更新,所以我添加了一个ORDER BY“ID”DESC并将结果限制为1.因此,ContentProvider每次只返回1个结果。这并没有什么不同。

对第一个问题的任何帮助也可以解决第二个问题。我读了一些不在Activity中进行Web服务调用的地方,这导致我使用Service类来轮询Web服务。仅供参考,这是一个只有少数客户的内部应用程序。

感谢您的反馈。

编辑: 以下是其中一个查询的必要代码:

Cursor geoEllipseDatas = managedQuery(GeoEllipseDataProvider.GEO_ELLIPSE_CONTENT_URI,
                projection, null, null, GeoEllipseDataProvider.ID + " DESC");
        boolean dataAvailable = geoEllipseDatas.moveToLast();

if (dataAvailable) {
    // parse the data out of the cursor
    String targetId = geoEllipseDatas.getString(1);
    ...
}

1 个答案:

答案 0 :(得分:0)

  1. 在采用两种方法(ContentProvider和直接数据库访问)之后,我个人发现ContentProvider是较少的错误来源。它们很容易访问/设置只是使用内容解析器,它们迫使你实际考虑URI,你会得到它们带来的所有好处(比如那些URI上的Intent过滤器,......)。

  2. 确保正确关闭游标,释放内存,......很难说没有任何代码。


  3. 根据我对managedQuery用例的理解,您应该在活动的onCreate方法中调用它。如果你在其他地方调用它,我认为在做另一个managedQuery之前调用stopManagingCursor是安全的(我不知道该函数是否为你自动完成,需要查看源代码)。 / p>

    此外,问题可能出在您的内容提供商,这将触发该光标的更新,这将触发另一个查询,这将触发更新,这将... ...