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


        android数据库操作的基础有三个类:SQLiteOpenHelper,SQLiteDatabase和Cursor。其中,SQLiteOpenHelper会建立一个数据库连接,它虽然可以调用多次getWritableDatabase或getReadableDatabase方法,但在彻底关闭db之前,返回的db对象其实是同一个。
        也就是说,如果实例化两个SQLiteOpenHelper,建立两个数据库连接同时操作数据库,会报出数据库已锁定的异常,操作将无效。
        而对于db对象,如果将其彻底关闭,就不能再用来操作数据库,必须重新获取一次。而获取db的过程是比较费时的。

        关于android的db对象,让我困惑的一点是db对象用完后是否要关闭。网上一般有这样几种意见:
        1 db对象开启后就用不关闭。
        2 保持一个单例的db引用,在程序退出前或不再使用数据库时关闭。
        3 每次使用db都要关闭。

        4 使用AtomicInteger 计数器来控制db的开启和关闭。


    我感觉上面的方案都有其问题:
        1让人感觉就不对头,而且android会不停的报出由于数据库永不关闭造成溢出的警告。    2单例的db问题是,首先无法区分readable和writable,而且很多时候无法确定app退出或不使用数据库的时间点。
        3每次都关闭db,让人怀疑是否会影响性能。
        4用计数器来维持db的引用,增加了代码复杂性。另外,db本身的close方法只是释放了一个引用,只有当所有的引用都被释放后,db才会真正关闭。因此我怀疑计数器是否和db本身的控制机制重复了。

        我想,在没有明显性能影响的情况下,还是每次都关闭db,也能让android日志输出好看一点。

        但即使这样,还是有一个问题,当用ContentProvider返回一个Cursor时,db是不能关闭的,而调用方只能自己关掉Cursor,无法关闭db。不知道ContentProvider是否有一个机制自动关闭db。

        关于Cursor,Cursor使用完必须关闭,否则很容易内存溢出,android也必会报出异常。为了保证Cursor的关闭,可以将Cursor的生命周期和Activity等组件绑定,或者将close方法放在finally代码块中。

        还有一个问题,是Cursor在ContentProvider中跨进程传递机制。我自定义了一个继承MatrixCursor的类,重写了getInt方法,但在调用方处,getInt方法并没有被覆盖。这说明并不是Cursor对象跨进程边界被传递了,具体机制以后有机会可以研究下。


       
  • 相关阅读:
    centos7 做rails 执行rails server 报错
    centos 7 安装 rvm 超时
    centos7 打造基于python语言Selenium2自动化开发环境
    RubyMine8 安装
    linux 下安装 RZ SZ命令 以及使用
    centos 7.2 安装mysql 修改 初始密码
    win10系统配置FTP
    Windows环境安装MySQL8.0.11
    IntelliJ IDEA 2017 上传本地项目至码云
    IntelliJ IDEA 2017.3 搭建一个多模块的springboot项目(三)
  • 原文地址:https://www.cnblogs.com/yuanchongjie/p/4448359.html
Copyright © 2020-2023  润新知