探讨SQLiteDatabase的优雅使用

Android SQLite连接管理与防崩实践指南 SQLite是Android平台最基础的本地数据库技术,其核心并非SQL语法本身,而是数据库连接的生命周期管理与线程安全机制。理解SQLiteDatabase的OPEN/CLOSED/INVALID状态机、SQLiteOpenHelper的引用计数原理,以及ContentValues对null值的严格类型处理,是避免‘no such table’和‘attempt to re-open’等高频崩溃的关键。在真实工程中,连接必须与业务原子性对齐,而非绑定Activity生命周期;采用ThreadLocal连接 阅读详情

不少人在使用SQLiteDatabase数据库时都很纠结,到底如何使用才算优雅?本文就此问题进行探讨。   

使用SQLiteDatabase,不外乎下面几种方式:

1. 在每个CRUD方法开始时调用getWritableDatabase()取得数据库,方法结束时close db

2. 在每个activity、service等生命周期开始时new一个新db对象,取得数据库连接;然后在destroy时close db

3. 在Application定义一个全局的数据库对象

4. 单例模式

先看第一种。缺点一大堆:代码臃肿;每次查询都要打开关闭数据库,性能方面也受到影响;最致命的一点是,有时候查询需要返回一个Cursor对象到其他地方使用,比如ListView,但是db又在查询方法结束时close了,导致运行直接抛异常。所以这种方式最好不用。

第二种方式和第一种类似,只是把打开关闭db的位置挪了一下,使db对象的生存范围扩大了一点。如果在onDestroy()中关闭,又会带来另外一个问题:打开新activity时,老activity只是被隐藏了,还在,导致打开的db越来越多,显然不可取。不过这种方式可以改进一下,改在onResume()中生成db,onPause()中关闭db,这样能保证系统中不会有多余的db实例,但仍不是很优雅。

第三种方式保证系统在运行中仅持有一个db实例,但是问题来了,在哪里close db呢?onTerminate()?不行,系统开始运行时会执行application的onCreate(),但是退出时不会执行onTerminate(),不信的话可以试一下。

最后讨论一下本文的重头戏,单例。

普通的单例模式,在我看来,和第三种application模式本质上是相同的,没区别,当然也就存在application方式的问题。而且,还会有其他问题。在创建SQLiteOpenHelper时需要传递一个Context进去,假如Activity A创建了这个db,然后其他Activity也在使用这个单例对象,而Activity A又需要被销毁,但是由于单例对象持有这个Context,导致Activity A不能被有效销毁。

怎么办?

完美解决

还是使用单例,不过需要改进一下。

首先,针对close问题,我们设一个计数器,在activity的onCreate()方法get单例实例,计数器加1,在onDestroy()方法释放,计数器减1,当计数器为0时,close db。

其次,创建SQLiteOpenHelper不使用activity的context,改用application的context。

DbAdaptor代码如下:

public class DbAdaptor {
    
    private static final String DATABASE_CREATE =
            "create table users (_id integer primary key autoincrement, " +
            "account text not null, password text not null);";
    private static final String DATABASE_NAME = "test";
    private static final int DATABASE_VERSION = 2;
    
    private static int count;
    private static DbAdaptor dbAdaptor = null;
    private SQLiteDatabase mDb; 

    class DbHelper extends SQLiteOpenHelper{

        public DbHelper(Context context) {
            super(context.getApplicationContext(), DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(DATABASE_CREATE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS users");
            onCreate(db);
        }
    }
    
    private DbAdaptor(Context ctx){
        DbHelper help = new DbHelper(ctx);
        mDb = help.getWritableDatabase();
    }
    
    public static DbAdaptor getInstance(Context ctx){
        if(null == dbAdaptor){
            dbAdaptor = new DbAdaptor(ctx);
        }        
        count++;
        
        return dbAdaptor;
    }
    
    public void release(){
        count--;
        if(count == 0){
            mDb.close();
            dbAdaptor = null;
        }
    }
}
注意一定要使用application的context;release时不仅仅要close db,还要将dbAdapter设为null。

每个需要使用数据库的activity都要在onCreate()中调用getInstance(),在onDestroy()中调用release(),注意保证这两个方法都只调用一次,否则count计数器不能正确增减。这些代码没必要在每个activity都写一遍,定义一个基类就可以了,子activity通过调用getDataBase()来使用db,代码如下:

public class BaseActivity extends Activity{

    private DbAdaptor db;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        db = DbAdaptor.getInstance(this);
    }
    
    @Override
    protected void onDestroy() {        
        super.onDestroy();
        
        db.release();
    }
    
    public DbAdaptor getDataBase(){
        return db;
    }
}
这就是单例加计数器模式,优雅而华丽!

Android SQLCipher数据库加密:从原理到实战的完整指南 在移动应用开发中,数据安全是保障用户隐私和业务合规的基石。SQLite作为Android平台默认的轻量级数据库,其未加密存储的特性使得敏感数据面临泄露风险。通过引入加密层,可以对数据库文件进行整体加密,确保即使设备被非法访问,数据内容也无法被直接读取。SQLCipher作为SQLite的权威加密扩展,采用256位AES算法,为整个数据库文件(包括数据页、索引和日志)提供透明加密,有效解决了原生SQLite的明文存储安全隐患。这一技术对于金融、医疗、企业办公等涉及敏感数据的应用场景具有重要价值,能够帮助开发者 阅读详情

相关推荐

SQLCipher Hook机制深度解析:自定义加密策略与Android数据库安全实践

在移动应用开发中,数据库安全是保护用户敏感数据的关键环节。SQLite作为轻量级数据库被广泛使用,但其默认不加密的特性使得数据文件容易暴露。SQLCipher作为SQLite的加密扩展,通过透明的加密层解决了这一问题。其核心原理在于在数据库操作的生命周期中插入自定义逻辑,允许开发者精细控制加密参数和性能优化。这种技术价值在于平衡安全性与性能,例如通过调整密钥派生迭代次数来增强抗暴力破解能力,或优化页面大小以提升I/O效率。应用场景涵盖金融、医疗等高安全要求的App,其中Hook机制允许在数据库打开前后执行自

weixin_30698297的博客 392

SQLiteOpenHelper的getReadableDatabase()和getWritableDatabase()方法理解灵感

getReadableDatabase()和getWritableDatabase()两个方法都是用来获取数据库对象的,那么它们有什么不同呢?首先说一下,它们的 相同点和不同点相同点1, 获得一个数据库的对象实例 2, 如果数据库没有创建,那么就创建一个,并且创建完数据库之后打开数据库,返回一个数据库对象 3, 如果数据库已经创建,那么就打开数据库,并且返回一个数据库对象不同点getReadab

AnyingVirusKing的博客 2376

Android SQLite数据库开发实战:从SQLiteOpenHelper到DAO模式完整指南

数据持久化是移动应用开发的核心基础,它确保应用数据在会话间得以保存和复用。其实现原理通常依赖于本地数据库技术,通过在设备存储中创建结构化的数据文件来实现。在Android生态中,SQLite作为内嵌的轻量级关系型数据库,因其零配置、单文件管理和系统级集成而成为本地存储的首选方案。这一技术价值在于为应用提供了高效、可靠的结构化数据管理能力,无需网络依赖。其典型应用场景包括用户偏好设置、离线数据缓存、以及笔记、记账等工具类应用的数据存储。本文聚焦于Android Studio中SQLiteOpenHelper的

weixin_33968104的博客 541

数据库的增删查改--Cursor结果集和execSQL和rawQuery方法的使用--SQLiteDatabase类的getWritableDatabase和getReadableDatabase方法

数据库的增删查改--Cursor结果集的execSQL和execSQL方法的使用--SQLiteDatabase类的getWritableDatabase和getReadableDatabase方法

qq_45491681的博客 3218

SQLCipher免费集成指南:跨平台数据库加密实战与安全解析

数据库安全是应用开发中的基础需求,尤其在移动端和桌面端,本地数据存储面临明文泄露风险。其核心原理在于对存储层进行透明加密,确保数据在静息状态下无法被直接读取。这项技术的核心价值在于以较低成本为应用数据提供“防弹衣”级别的保护,无需重构整个数据层即可实现全库级别的安全加固。在金融、医疗、企业通讯等对数据隐私要求严格的领域,数据库加密已成为标配能力。本文聚焦于SQLCipher这一成熟方案,针对其商业授权限制,详细梳理了Android、iOS、Python、Node.js等主流平台的免费集成路径,并通过实战代码

weixin_33690367的博客 335

MFRC522防冲突机制详解:当两张IC卡同时靠近读写器,会发生什么?

本文深入解析了MFRC522芯片在多张IC卡同时靠近RFID读写器时的防冲突机制,重点介绍了二叉树搜索算法在比特级的实现原理。通过详细的寄存器配置优化和实际工程案例,展示了如何有效解决信号碰撞问题,提升多卡场景下的读写性能。

weixin_29191669的博客 429

SQLiteDatabase

SQLiteDatabase 一、SQLite: (一)、简介:         除了可以使用文件或SharedPreferences存储数据,还可以选择使用SQLite数据库存储数据。 在Android平台上,集成了一个嵌入式关系型数据库——SQLite。          SQLite3支持 NULL、INTEGER、REAL(浮点数字)、TEX

ElevenDGQ的博客 4898

安卓手机必备:Auto.js快手极速版自动刷视频避坑指南(含最新3.0脚本)

本文是一份安卓自动化工具Auto.js的全面实践指南,重点解析了如何搭建稳定运行环境、配置关键权限以及管理脚本。针对快手极速版等应用的自动化需求,文章详细介绍了设备选择、Auto.js版本对比、各品牌手机后台保活设置,并强调了脚本安全与调试技巧,帮助用户有效避坑,实现自动化任务的稳定执行。

i7j8k9l的博客 782

SQLiteDatabase单例模式

SQLiteDatabase 单例模式

zhaotun123的博客 1064

告别校准烦恼:用ADS1220和松下ERA3电阻实现±0.05℃精度的Pt100测温方案(附完整电路图)

本文详细介绍了如何利用TI的ADS1220 24位ΔΣ ADC与松下ERA3系列精密电阻构建±0.05℃精度的免校准Pt100测温系统。通过比例测量法架构和关键器件选型,解决了传统方案中的校准繁琐和长期稳定性问题,特别适用于工业控制、医疗设备等高精度温度测量场景。

weixin_30740581的博客 613

保姆级教程:用ROS2 Humble + Gazebo Classic 从零搭建一个能键盘控制的差分AGV模型

本文提供了一份详细的ROS2 Humble与Gazebo Classic教程,指导用户从零开始搭建一个键盘控制的差分AGV模型。内容涵盖环境配置、Xacro文件设计、Gazebo仿真集成以及键盘控制实现,特别针对常见问题提供解决方案,帮助开发者快速掌握ROS2机器人仿真技术。

weixin_30387423的博客 169

android sqlite 分析,Android源码分析------SQLiteDatabase(1)

看了SQLiteDatabase的replace接口的源码,感觉写的很好,有些可以借鉴的地方,记录如下:publiclongreplace(Stringtable,StringnullColumnHack,ContentValuesinitialValues){try{returninsertWithOnConflict(table,nullColumnHack,initi...

weixin_29521135的博客 217

西门子 S7-200 SMART 系列六:手把手教你配置S7-200 SMART Modbus RTU

最新发表:https://www.ics-pedia.com/%e8%a5%bf%e9%97%a8%e5%ad%90-s7-200-smart-%e7%b3%bb%e5%88%97%e5%85%ad%ef%bc%9a%e6%89%8b%e6%8a%8a%e6%89%8b%e6%95%99%e4%bd%a0%e9%85%8d%e7%bd%aes7-200-smart-modbus-rtu%e5%ae%9e%e4%be%8b/

John_09040211的博客 3282

StorIO 与 RxJava 完美结合:实现响应式数据库编程

StorIO 是一个为 Android 平台设计的响应式数据库编程库,它将 SQLiteDatabase 和 ContentResolver 与 RxJava 无缝集成,为开发者提供了简洁而强大的数据库操作 API。通过 StorIO,你可以轻松实现数据的响应式处理,让数据库操作变得更加流畅和高效。 ## 什么是响应式数据库编程? 响应式数据库编程是一种基于观察者模式的编程范式,它允许你以声明

gitblog_00539的博客 706

半导体工艺仿真:离子注入工艺仿真_(8).损伤和缺陷仿真

离子注入工艺在半导体制造中是一个重要的步骤,用于在半导体材料中引入特定的掺杂剂。然而,离子注入过程中不可避免地会产生损伤和缺陷,这些损伤和缺陷会直接影响器件的性能和可靠性。因此,对离子注入工艺中的损伤和缺陷进行仿真研究是必不可少的。本节将详细介绍如何使用仿真软件对离子注入过程中的损伤和缺陷进行建模和分析。

2401_87715305的博客 1339

手把手教你学SIMULINK模块库文件专栏--Scope 模块详解

模块是 Simulink 中的一个信号接收模块,用于实时显示信号波形。该模块可以捕捉并可视化仿真过程中信号的变化,帮助用户直观地分析系统的动态行为。模块都能提供强有力的支持。通过深入了解其参数的影响及结合 MATLAB 脚本的应用,读者可以更加有效地利用这一模块进行仿真和研究。此外,通过实际应用场景的扩展以及常见问题解答部分的帮助,能够更好地掌握。模块是一个非常实用的工具,适用于需要实时显示信号波形的各种场景。模块的参数,可以进一步增强学习体验。模块参数的影响,下面我们将详细探讨每个参数如何影响波形显示。

MHD0815的博客 312

android mysql sqlite_android SQLite数据库在Android中的API

上次我向大家介绍了SQLite的基本信息和使用过程,相信朋友们对SQLite已经有所了解了,那今天呢,我就和大家分享一下在Android中如何使用SQLite。现在的主流移动设备像Android、iPhone等都使用SQLite作为复杂数据的存储引擎,在我们为移动设备开发应用程序时,也许就要使用到SQLite来存储我们大量的数据,所以我们就需要掌握移动设备上的SQLite开发技巧。对于Androi...

weixin_29341747的博客 301

基于改进YOLOv5的小目标检测 | 添加CBAM注意机制 + 更换Neck网络之BiFPN + 增加高分辨率检测头

本文针对图像中小目标难以检测的问题,提出了一种基于YOLOv5的改进模型。在主干网络中,加入CBAM注意力模块增强网络特征提取能力;在颈部网络部分,使用BiFPN结构替换PANet结构,强化底层特征利用;在检测头部分,增加高分辨率检测头,改善对于微小目标的检测能力。本文算法在无人机数据集VisDrone2019数据集上进行了多次对比实验,结果表明本文算法可以有效地检测小目标。🌈

小哥谈 2937

190413-数据库学习记录

Android系统中的数据库 采用的是SQLite,一个轻量级的数据库 在安卓代码中对应的对象类的名字是SQLiteDatabase, 并配置了一套SQLiteDatabase的方法SQLiteDatabase.methods() 一旦在程序中建立了SQLiteDatabase, 那么就可以使用SQLiteDatabase.methods()进行操作. 建立数据库 *静态方法如下 操作如下 SQL...

weixin_30716725的博客 104

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Android-操作SQLite数据库(二)

一、概述 在操作SQLite数据库(一)中,我们为了判断底层数据库是否包含news_inf数据表,采用的处理方法十分繁琐,程序先尝试向news_inf数据表中插入记录,如果程序抛出异常,则在异常捕获catch块中创建news_inf数据表,然后再插入记录。在本例程中,使用更为优雅的方式来操作数据库——SQLiteOpenHelper类 在实际项目中很少使用SQLiteDatabase的方法来打...

往事似水拂流年的博客 309

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

打造android ORM框架opendroid(五)——数据更新的实现

转载自:http://blog.youkuaiyun.com/qibin0506/article/details/43148523 在上一篇博客《打造android ORM框架opendroid(四)——优雅的删除数据》中,我们介绍了opendroid是如何优雅的从数据库中删除数据的,也可以看到opendroid的设计是如此的简单,其实opendroid只是我作为兴趣或者说是抱着试试的态

u010944680的专栏 494

StorIO 架构解析:从 SQLite 到 ContentResolver 的设计哲学

StorIO 是一个为 Android 平台打造的响应式数据访问库,它通过统一的 API 抽象简化了 SQLiteDatabase 和 ContentResolver 的操作复杂性。作为现代 Android 开发的重要工具,StorIO 采用 Reactive 设计模式,让开发者能够以更简洁、更优雅的方式处理本地数据持久化与内容解析。 ## 核心架构设计:响应式数据访问层 StorIO 的核心

gitblog_00211的博客 616

LitePal源码解读:Connector数据库连接管理

在Android开发中,数据库连接管理一直是开发者面临的一大挑战。你是否还在为SQLiteOpenHelper的复杂配置而烦恼?是否在处理多数据库版本升级时感到力不从心?是否在管理数据库存储路径时遇到各种兼容性问题?本文将深入剖析LitePal框架中的Connector类,带你彻底理解LitePal如何优雅地解决这些问题,实现高效、灵活的数据库连接管理。 读完本文,你将能够: - 理解LiteP...

gitblog_00188的博客 790

Android记事本开发实战:从MVC架构到APK打包的完整指南

在Android应用开发中,数据持久化是核心基础技术之一,它决定了应用如何高效、可靠地存储和管理用户数据。其原理通常涉及本地数据库、文件系统等存储方案,其中SQLite作为Android内置的关系型数据库,因其轻量、无需服务器和原生支持SQL查询而成为结构化数据存储的首选。掌握数据持久化技术对于构建任何需要离线工作或快速数据检索的应用都具有重要价值,尤其在笔记、待办事项、个人账本等工具类应用场景中尤为关键。本文以开发一个Android记事本应用为具体案例,深入解析了如何使用SQLiteOpenHelper实

weixin_34197488的博客 477
上一篇: Android透明无边框圆形进度条之最简单实现
下一篇: 日期选择器DatePickerDialog简化使用
JavaSecret
博客等级 码龄15年 2粉丝 4原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值