android Cursor的自动管理方式

Cursor+Claude-3.5生成Android app Cursor 与 Claude 携手,构建完整流程,助力开发者从概念快速迈向实现,大幅缩短开发周期,打造更优质创新的 Android 应用 阅读详情

  新手在使用数据库的时候,很容易忘记关闭Cursor,造成严重内存泄漏。有什么好的方法解决这个问题呢?除了自己管理Cursor,有什么办法把Cursor交给系统管理,而不需要自己主动close呢?manageQuery可以为你维护这个cursor。在你退出activity时为你自动关闭。

  The method managedQuery(Uri, String[], String, String[], String) from the type Activity is deprecated。

android官方文档推荐用CursorLoader类来取代。

  我们先来分析一下manageQuery是如何管理cursror的

 private static final class ManagedCursor {
        ManagedCursor(Cursor cursor) {
            mCursor = cursor;
            mReleased = false;
            mUpdated = false;
        }

        private final Cursor mCursor;
        private boolean mReleased;
        private boolean mUpdated;
    }
    private final ArrayList<ManagedCursor> mManagedCursors =
        new ArrayList<ManagedCursor>();

   public final Cursor managedQuery(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        Cursor c = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);
        if (c != null) {
            startManagingCursor(c);
        }
        return c;
    }
    public void startManagingCursor(Cursor c) {
        synchronized (mManagedCursors) {
            mManagedCursors.add(new ManagedCursor(c));
        }
    }
  protected void onDestroy() {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);
        mCalled = true;

        // dismiss any dialogs we are managing.
        if (mManagedDialogs != null) {
            final int numDialogs = mManagedDialogs.size();
            for (int i = 0; i < numDialogs; i++) {
                final ManagedDialog md = mManagedDialogs.valueAt(i);
                if (md.mDialog.isShowing()) {
                    md.mDialog.dismiss();
                }
            }
            mManagedDialogs = null;
        }

        // close any cursors we are managing.
        synchronized (mManagedCursors) {
            int numCursors = mManagedCursors.size();
            for (int i = 0; i < numCursors; i++) {
                ManagedCursor c = mManagedCursors.get(i);
                if (c != null) {
                    c.mCursor.close();
                }
            }
            mManagedCursors.clear();
        }

        // Close any open search dialog
        if (mSearchManager != null) {
            mSearchManager.stopSearch();
        }

        getApplication().dispatchActivityDestroyed(this);
    }

  看来这几个方法就已经非常明确了。将cursor封装之后放到一个ArrayList中,在Activity的Destroy方法中关闭cursor,Activity正常销毁一定会走OnDestroy()方法的,这样可以保证cursor会被关闭。
LoaderManager方法有下面几个方面更胜一筹:
1. startManagingCursor管理Cursors,而LoaderManager管理Loader<D>对象。Loader<D>是一个模板类,D是一个包含了需要载入数据的类。也就是说,数据源并不必须是Cursor,它可以是List、JSONArray。。。任何类。LoaderManager与它包含的数据内容解耦了,所以更加灵活。
2. 调用startManagingCursor会导致Activity在已经加入管理的Cursor上调用requery()方法。在第一篇文章中提到过,在UI线程执行requery()方法代价非常高。相反的是,Loader<D>的子类会异步载入(译者注:另外再开一个线程,就叫异步了。)数据,所以使用LoaderManager永远不会产生阻塞UI线程的情况。
3. startManagingCursor在配置变化(例如横竖屏切换)时,并不会保持Cursor的状态。麻烦的是,每次Activity由于配置变化(比如,简单的横竖屏切换),都会导致Cursor下回并且被重新查询。LoaderManager就智能多了,当配置变化时,它会保持它里面的Loader们的状态,所以并不需要重新查询数据。
4. LoaderManager提供无缝的数据监测。任何时候,当Loader的数据源改变,LoaderManager将会从对应的Loader上面接收到一个新的同步载入数据,并将更新数据返回给客户端(注意:仅当Loader被正确实现,LoaderManager才会接收到这些数据变化通知。我们将会在该系列的第三篇文章讨论自定义Loaders的实现)。

  CursorLoader使用LoaderManager管理Cursor

使用方法如下

LoaderCallbacks<Cursor> callback= new  LoaderCallbacks<Cursor>() {

               @Override
               public Loader<Cursor> onCreateLoader(int id, Bundle args) {
                      // 返回自己需要的CursorLoader
                      return null ;
              }

               @Override
               public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
                      // 使用swapCursor()方法,以使旧的游标不被关闭.
                      simpleCursorAdapter.swapCursor(cursor);
              }

               @Override
               public void onLoaderReset(Loader<Cursor> loader) {       、
                       // 一般写这样写
                       simpleCursorAdapter.swapCursor(null);
              } 
}; 
getLoaderManager().initLoader(0, null, callback);


需要注意的是当使用initLoader()时,如果指定ID的装载器已经存在,则它使用这个装载器.如果不存在呢,它将创建一个新的.但是有时你却是想丢弃旧的然后开始新的数据,要使用restartLoader()方法。


欢迎扫描二维码,关注公众号






Cursor 3.0实战:用自然语言开发安卓APP 自然语言编程正从概念走向工程落地——它不是替代开发者,而是将软件开发的核心动作从‘写代码’升维为‘表达需求’。其底层依赖智能体(Agent)协同、Composer混合专家架构与强化学习驱动的决策逻辑,实现对Android SDK、Room数据库、CameraX、RESTful API等技术栈的零认知调用。用户无需掌握Kotlin语法或Gradle配置,仅需描述业务目标(如‘扫码更新库存’‘低于5件弹红框提醒’),系统即可自动生成可编译、可调试、可上架的原生APK。该范式显著降低中小业务方、产品经理与个体创业 阅读详情

相关推荐

基于CURSOR的APP自动化测试框架实战指南(一)

本文详细介绍了基于CURSOR的APP自动化测试框架的实战指南,包括环境配置、项目结构设计和测试用例编写。CURSOR框架通过可视化操作简化了复杂配置,适合中小型团队快速验证核心业务流程和进行多设备兼容性测试。文章还提供了Python依赖管理和日志模块的最佳实践,帮助开发者高效搭建自动化测试环境。

weixin_42554151的博客 218

Study on Android【五】--自定义ContentProvider的语义

<br />    【安卓航班】Android做到现在。开始感觉到Android确实还是太年轻。系统本身好不够成熟,相关文档更是少的可怜。在Android的旅途中到处是暗坑陷阱,掉进去摔得半死,还只能靠自己琢磨着爬出来。<br />   想在大部分工作集中在了定义一套ContentProvider以及上层的显示控件上。一个ContentProvider向外提供的接口十分有限,但就是这几个东西你要表征出正确(标准就是和系统ContentProvider一致的行为)的语义,还是很费功夫的。至少我就摔了好几个跟头

yanhongzhan的专栏 413

Android中Cursor的使用

在Android开发中,我们经常需要与数据库进行交互,而Cursor提供了一种方便的方式来处理查询结果集。上述代码创建了一个名为"mydatabase.db"的数据库,并在其中创建了一个名为"mytable"的表,表中包含"id"和"name"两列。在示例中,我们选择了所有列,没有设置选择条件和排序方式。然后,我们可以通过索引获取相应的列值,并对结果进行处理,例如打印或展示在用户界面上。最后,我们记得在使用完Cursor和数据库后关闭它们,以释放资源。上述代码中,我们首先获取可读的数据库实例,然后使用。

HnrzLinux的博客 1723

Android Studio Cursor里面的数据获取并且使用

在使用Android Studio,使用数据库时查询用到cursor。但是怎么查询到之后,怎么使用里面的数据呢?在这里以我用的Sqlite为例:使用Cursor对象获取查询结果rawQuery()方法返回的查询结果为Cursor类的对象。Cursor可称为”数据指针“,要读取查询结果中某一个记录,就必须将Cursor指标指到它,之后才能读取其内容。那么怎么页面之间传输获取到的数据呢?

qq_52078947的博客 4456

工业质检新利器:手把手教你用AD-DINOv3实现零样本缺陷检测(附MVTec AD实战)

本文详细介绍了AD-DINOv3框架在工业质检中的应用,通过零样本异常检测技术解决传统方法的标注成本高和泛化能力弱问题。文章包含技术原理解析、MVTec AD数据集实战部署、模型训练流程及工业部署优化技巧,帮助读者快速掌握这一创新技术。

seed的博客 763

告别倍福开发板:手把手教你用SSC工具为STM32生成EtherCAT从站代码

本文详细介绍了如何使用SSC工具为STM32生成EtherCAT从站代码,帮助开发者在不依赖倍福开发板的情况下实现高效的工业以太网通信。通过SSC工具的配置、XML文件设计、代码移植与硬件适配等步骤,开发者可以轻松构建自定义的EtherCAT通信系统,提升工业自动化项目的灵活性和效率。

weixin_33925615的博客 410

Android 数据库的Cursor封装,简化操作

不喜欢写注释因为较简单

WowCool 539

【三维重建】基于多视角图像的三维重建

基于多视角图像的三维重建》

m0_64446860的博客 8758

android sqlite数据库封装 实现crud

android常用的数据保存方式有文件、sharepreferences、数据库、网络、contentprovider集中方式。        文件存储方式,经常使用在缓存整个页面数据,比如电子书内容、html数据等。        sharepreferrences存储方式,实质也就是xml文件存储的封装,常用于存储配置参数数据。当然也可以用文件存储+Properties来存储参数数据。

xiangxue336的专栏 5106

手把手教你用Wireshark抓包分析Profinet非周期通信(附实战案例)

本文详细解析了PROFINET非周期通信(RTA)的技术原理与实战应用,通过Wireshark抓包分析,揭示从PLC请求到驱动器响应的完整对话过程。涵盖实验环境搭建、关键配置步骤、典型参数访问流程及故障诊断案例,帮助工程师深入理解并优化工业网络通信性能。

Black的专栏 1048

高通camera:PDAF的配置与测试

确认相关log日志都已经打开了之后,判断是在3A算法中没有应用到PDAF,可能是之前在调试AF效果的时候关闭了PDAF,打开效果文件对应的文件夹,在\kamorta_lce_S5K3P9\Scenario.Default\XML\STATS。在log中搜索af_pdaf_proc_pd_single,这个函数是pdaf算法中的,源码被封装了,这里看不到,因此只能通过log打印出来的参数来分析pd是否正确,主要参数有pd ,defocus,confidence。PDAF的配置与测试。

arvin_xiong的博客 2485

android关闭cursor的方法

今天review了一下之前写播发器的代码,发现了个问题,在音乐数据信息查询后,没有及时关闭cursor,虽然目前使用没什么大问题,可是在音乐数据比较多时,可能会有不好的影响,所以我还是觉得有必要对Cursor添加关闭处理,再贴一下音乐播放器《Android音乐播放器 -- 数据处理》中数据处理的代码 /** * 用于从数据库中查询相同专辑的歌曲信息,保存在List集合当中 *

S.H.的部落格林 2630

【AutoDL + Langchain-Chatchat】从零构建高效本地 RAG 知识库问答系统:实战保姆级教程(含避坑指南)

本文详细阐述如何在AutoDL云平台,如何利用Langchain-Chatchat构建高效的本地RAG知识库问答系统,并深入解析RAG架构。从环境搭建到实战部署,从问题排查到性能优化,提供一份全面实用的指南,助力开发者快速构建智能问答应用。

拾光夕拾的博客 1803

Android中Cursor关闭的问题

Cursor是Android查询数据后得到的一个管理数据集合的类,正常情况下,如果查询得到的数据量较小时不会有内存问题,而且虚拟机能够保证Cusor最终会被释放掉。     然而如果Cursor的数据量特表大,特别是如果里面有Blob信息时,应该保证Cursor占用的内存被及时的释放掉,而不是等待GC来处理。并且Android明显是倾向于编程者手动的将Cursor close掉,因为在源

学习记录 1579

matplotlib保存图片设置分辨率总是96dpi,好烦躁,教你一招轻松解决

matplotlib保存图片设置分辨率总是96dpi,好烦躁,教你一招轻松解决 目录 matplotlib保存图片设置分辨率总是96dpi,好烦躁,教你一招轻松解决 #使用plt.savefig("cm.png",dpi = 300)为什么不管用 #plt.rcParams也不管用 #解决方案 在做论文的过程中,许多期刊或者会议对图片的分辨率有明确的要求,例如,dpi=300。 之前画曲线图都是采取保存方式为savefig(dpi=300),然后查看保存图片的属性信息,然而你看到的现象是

data+scenario+science+insight 8799

FPGA 学习笔记:Vitis IDE launch failed 的解决方法

FPGA 学习笔记:Vitis IDE launch failed 的解决方法

坚韧与专注 1万+

Cursor使用后有感

简单尝试Cursor的AI编程后,让我感触良多。

Uncommon的博客 883

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

关于android的SQLiteDatabase和Cursor的一些疑问

android数据库操作的基础有三个类:SQLiteOpenHelper,SQLiteDatabase和Cursor。其中,SQLiteOpenHelper会建立一个数据库连接,它虽然可以调用多次getWritableDatabase或getReadableDatabase方法,但在彻底关闭db之前,返回的db对象其实是同一个。     也就是说,如果实例化两个SQLiteOpenHelper,

yuan_chongjie的专栏 1894

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Android Cursor 数据遍历与访问详解

在 Android 开发中,Cursor 作为数据库操作的核心组件,专门用于处理 SQLite 查询结果集的遍历和数据访问。下面将详细解析其实现原理和使用方法。

skywangqianl的博客 1094

Android Cursor(游标)

关于游标的知识点 SQLite执行查询后返回Cursor对象 Cursor 是一个随机的数据源。 Cursor 是每行的集合。 使用 moveToFirst() 定位第一行。 你必须知道每一列的名称和数据类型。 所有的数据都是通过下标取得。 游标内容 Cursor:游标接口,提供了遍历查询结果的方法。 【你可以Cursor cursor =new

默 3244

cursor管理

cursor管理   使用cursor的时候需要注意在使用完之后将其关闭,什么时候关闭也是一个需要注意的问题,稍不小心就可能会出错。我们自己管理cursor可能不是那么容易,问题出现这个或那样的问题,Android系统提供了一套curosr的管理,下面让我们来了解一下。 managedQuery和query的区别   我们都知道在Android系统中,SQLit...

chadm.xiang 512

Agent的安卓时刻到了!MCP协议下的Cursor与Milvus部署指南

恭喜你,发现了大模型与Agent的核心差距。 通过将“万能百科全书”大模型与 规划模块(分解任务步骤)、记忆模块(存储历史与知识,通常是milvus等向量数据库)、工具调用模块(执行API/代码,比如计算器、天气、炒股软件结合,Agent可以帮助我们更好的完成如股价分析、智能出行规划在内等具体的任务。

Gaga246的博客 2002

Cursor试用限制如何突破?go-cursor-help开源工具的深度技术解析

# Cursor试用限制如何突破?go-cursor-help开源工具的深度技术解析 面对Cursor AI编程助手试用限制的技术挑战,go-cursor-help项目提供了一套完整的设备标识重置解决方案。这款开源工具通过设备ID修改、配置文件清理和进程管理三大核心技术,实现了Cursor试用状态的智能重置,为开发者提供了持续使用AI辅助编程功能的技术路径。 ## 技术架构深度解析:设备标识重

gitblog_01238的博客 1047
上一篇: Java编译时注解自动生成代码
下一篇: Android apk打包过程
robert_chao
博客等级 码龄15年 265粉丝 119原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值