大家好,本周技术拆解官的第一篇文章,给大家带来的是我们的新主题《独家食用指南系列》。作为新主题的第一篇系列文章,这次给大家分享下AndroidSQLite的“食用指南”。之所以会拿SQLite作为系列的开篇文章,也是因为最近接触到逆向AndroidSQLite数据库的工作,查阅了很多资料,我也想给这次调研做下总结,所以接下来我会分三篇文章来给大家好好讲讲这次逆向AndroidSQLite数据库的经历,首当其冲的第一篇,也就是《独家食用指南系列|AndroidSQLite的浅尝辄止》

本篇文章使用到的项目源码都在我的个人Github上面:https://github.com/lateautumn4lin/TechPaoding/tree/main/practice_demo/Cattle

1 认识SQLite

1.1 SQLite定义

SQLite是一款轻量级的关系型数据库,为什么是轻量级呢?主要是因为它占用资源很少,通常只需要几百K的内存就足够了,也因为它的结构足够简单,运算速度非常快,特别适合在移动设备上使用。

1.2 SQLite特点

  • 轻量级
    使用 SQLite 只需要带一个动态库(也就是NDK开发的SO库),就可以享受它的全部功能,而且那个动态库的尺寸想当小,因此对于移动端的使用来说可谓是“百利而无一害”。
  • 独立性
    SQLite 数据库的核心引擎不需要依赖第三方软件,也不需要所谓的“安装”。
  • 隔离性
    SQLite 数据库中所有的信息(比如表、视图、触发器等)都包含在一个文件夹内,方便管理和维护,具体的表现形式就是每个数据库就是一个db文件,相当于库与库之前是彼此隔离的。
  • 跨平台
    SQLite 目前支持大部分操作系统,不至电脑操作系统更在众多的手机系统也是能够运行,比如:AndroidIOS
  • 多语言接口
    SQLite 数据库支持多语言编程接口(在Android端话一般会使用JDK或者NDK来开发)。
  • 安全性
    SQLite 数据库通过数据库级上的独占性和共享锁来实现独立事务处理。这意味着多个进程可以在同一时间从同一数据库读取数据,但只能有一个可以写入数据(涉及并发问题的处理方式类似于另一个关系型数据库-MySQL)。
  • 弱类型的字段
    同一列中的数据可以是不同类型(编码自由者的福音、编码强迫症的噩梦)

1.3 SQLite数据类型

SQLite具有以下五种常用的数据类型,都是比较常见的基本类型:

类型 含义
NULL 值是一个 NULL 值
INTEGER 值是一个带符号的整数,根据值的大小存储在 1、2、3、4、6 或 8 字节中
REAL 值是一个浮点值,存储为 8 字节的 IEEE 浮点数字
TEXT 值是一个文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储
BLOB 值是一个 blob 数据,完全根据它的输入存储

以上就是关于SQLite的基本知识,大家大致了解就好,详细的信息可以看看它的WIKI:https://zh.wikipedia.org/wiki/SQLite

1.4 SQLite安装

关于SQLite的安装,这里我们举CentOS7来说,最简单的方式当然是“懒人一键安装”了

 sudo yum install sqlite-devel

安装好之后就可以和正常的数据库那样,大家就可以试试“增删改查”了,比如下面这样

  • 首先我们指定一个db文件进入交互式的界面,指定db文件也是为了我们之后的建表的操作能够得到存储

  • 然后就是正常对于数据库的“增删改查”了

当然在命令行的操作也并不是我们这次关心的重点,我们之后会利用Java的库来操作。

2 SQLite的调试工具

上面我们提到了SQLite它其实是一个关系型数据库,那么联想到MySQL的话,SQLite也有它的特定的可视化工具又或者可以说是调试工具,因为我们后面会利用这个工具来实时查看App的数据存储情况。

2.1 直接命令行调试

命令行调试的方式和上面我们说的在CentOS7操作数据库的方式基本类似,因为Android本身也是一个Linux系统,相关命令也是一致的。如果不嫌麻烦的话就是可以直接adb shell进手机系统去操作。

2.2 SQLiteStudio工具

相比于命令行我想更多人会选择可视化的工具来操作,这里我推荐一下我自己目前在使用的工具SQLiteStudio,其实在选择工具的时候我也是在很多工具中纠结了一番,不过其他工具不是不能实时连接Android机调试就是在安全加密方面功能方面差一截,所以最后直接选择了SQLiteStudio了。

最新版本的SQLiteStudioSQLiteStudio3.2,地址:https://sqlitestudio.pl/,
大家可以去官网下载,这也是个开源项目,要是大家有问题也可以去Github打扰那位大佬。

整体界面是这样的

照例演示下添加新数据库的流程

Database->Add a Database->打开自己选定好的db文件即可。

3 SQLite 基础类介绍

上面我们讲了SQLite的定义以及调试工具,下面我们要正式讲讲SQLite的使用了,这一篇我们暂且不深入源码,之后我会单独出一篇源码分析。在讲如何使用SQLite数据库之前,有必要介绍一下SQLite两个重要的类:SQLiteDatabaseSQLiteOpenHelper,这是SQLite数据库API中最基础的两个类。

3.1 SQLiteDatabase

Android的自带的SQLite库中,SQLite所有的操作都来源于SQLiteDatabase ,另一个类SQLiteOpenHelper也是基于该类衍生而来进行数据库的创建和版本管理的。我们简单看看这个类的分析


可以发现insertquery等熟悉的数据库操作的字眼,这些方法都是已经封装好的,我们只需要传入适当的参数即可完成诸如插入、更新、查询等操作。当然SQLiteDatabase也提供了直接执行SQL语句的方法,如

  • execSQL

    db.execSQL("create table if not exists " + TABLE_NAME +"(id text primary key,name text)");

  • rawQuery

    db.rawQuery("SELECT * FROM test", null);

3.2 SQLiteOpenHelper

SQLiteOpenHelperSQLiteDatabase的辅助类,通过对SQLiteDatabase内部方法的封装简化了数据库创建与版本管理的操作。它是一个抽象类,一般情况下,我们需要继承并重写这两个父类方法:

  • onCreate
    在初次生成数据库时才会被调用,我们一般重写onCreate生成数据库表结构并添加一些应用使用到的初始化数据
  • onUpgrade
    当数据库版本有更新时会调用这个方法,我们一般会在这执行数据库更新的操作,例如字段更新、表的增加与删除等

此外父类方法中还有onConfigureonDowngradeonOpen,一般项目中很少用到它们,如果大家需要进一步了解可以去看看官方文档。

3.3 SQLiteOpenHelper与SQLiteDatabase的关系

介绍完了SQLiteOpenHelper以及SQLiteDatabase之后,那它们是怎么关联在一起的呢?我们从源码中来看看

SQLiteOpenHelper提供了两个创建数据库的方法

  • getWritableDatabase

  • getReadableDatabase

从源码中我们可以看到,这两个方法有个共同点,也就是都调用了getDatabaseLocked这个方法,我们再看getDatabaseLocked这个方法

  • 第一步

  • 第二步

  • 第三步

根据上面的分析我们可以看到SQLiteOpenHelper是如何一步步通过调用SQLiteDatabase的方法来生成一个db实例的,也就表明了SQLiteOpenHelper是一个更高维度的SQLiteDatabase的封装。

3.4 SQLiteDatabase对象生成流程

总结了SQLiteOpenHelperSQLiteDatabase之间的关系后,我们捋一下SQLiteDatabase对象的生成流程,也可以当成我们之后在开发过程中使用的SQLite的一个模板,我们可以以下三种方式可以来生成SQLiteDatabase

  • 继承SQLiteOpenHelper,调用getWritableDatabase / getReadableDatabase打开或创建数据库(推荐初学者使用)
  • 调用SQLiteDatabase.openOrCreateDatabase打开或创建数据库
  • 调用Context.openOrCreateDatabase打开或创建数据库

三种方法最终都是要调用SQLiteDatabase.openDatabase方法

既然都调用了SQLiteDatabase.openDatabase,那我们看看它的源码

解释一下各个参数

  • String path
    数据库文件路径
  • CursorFactory factory
    用于构造自定义的Cursor子类对象,在执行查询操作时返回,若传入 null 则使用默认的factory构造Cursor
  • int flags
    用于控制数据库的访问模式,可传入的参数有

    • CREATE_IF_NECESSARY:当数据库不存在时创建该数据库文件
    • ENABLE_WRITE_AHEAD_LOGGING:绕过数据库的锁机制,以多线程操作数据库的方式进行读写
    • NO_LOCALIZED_COLLATORS:打开数据库时,不根据本地化语言对数据库进行排序
    • OPEN_READONLY:以只读方式打开数据库
    • OPEN_READWRITE:以读写方式打开数据库
  • DatabaseErrorHandler errorHandler
    当检测到数据库损坏时进行回调的接口,一般没有特殊需要传入 null 即可

可以看到,我们通过openDatabase生成SQLiteDatabase的实例,并且将db实例的状态置为开启,最终返回db实例

3.5 创建数据库的路径

SQLiteDatabase源码中有一行代码是关于db文件路径相关的

final File filePath = mContext.getDatabasePath(mName);

这段代码我们得到的路径是

/data/data/<package_name>/databases/

一般情况下我们在创建数据库时path参数只需传入“xxx.db”,系统自动会在该默认路径下创建名为“xxx.db”的数据库文件,这样做最大的好处就是安全,因为从Android7开始,Android的策略就限制了App彼此间的访问权限,这也使App的安全性得到了保证。

4 SQLite Demo开发

通过上面的关于SQLiteDatabase类的基本的了解,下面我们直接上手搞个Demo

4.1 创建MySQLiteOpenHelper

第一步我们使用最快捷的创建SQLiteDatabase的方式,也就是继承SQLiteOpenHelper来创建一个我们自己MySQLiteOpenHelper,如下

4.2 创建SQLiteCattleActivity

创建好了MySQLiteOpenHelper之后,我们需要在一个新的Activity中来使用它

这里我们使用两种方法来创建db实例,分别是SQLiteDatabase 自身的openOrCreateDatabase和我们创建的MySQLiteOpenHelpergetWritableDatabase来创建

4.3 连接SQLiteStudio实时调试

如上面的两个步骤,我们开发好了基本的App,实现了基本的点击按钮完成“增删改查的功能”,但毕竟数据库是在手机里面,我们要如何进行实时的数据库调试呢?下面介绍一种方法是基于SQLiteStudio进行的实时调试方案
由于SQLite数据库是以db文件的形式保存在手机目录上的,我们无法直接便捷的实时获取到SQLite的内容,因此我们需要借助SQLiteStudio的端到端通信功能来获取SQLite的数据。

4.3.1 SQLiteStudio环境配置

第一步我们需要导出SQLiteStudio Remote Jar包,导出的步骤是Tools->Get Android Connect Jar File来获取到Jar包,并把Jar包放在项目的根目录/libs下面。

我们需要开启SQLiteStudio SQLite数据库调试的权限,步骤是通过Tools->Open configuration dialog打开配置界面,在插件栏勾选SQLite选项。

4.3.2 Android项目环境配置

配置好了SQLiteStudio之后,下面我们来配置我们的App项目,我们之前已经引入了Remote Jar包,放在我们的根目录/libs下面,下面我们还需要项目的build.gradle文件中在写入implementation fileTree(include: ['*.jar'], dir: 'libs')来保证libs下所有的Jar包能够正常的导入。

导入Jar包之后我们只需要在我们的Activity中加上一行代码SQLiteStudioService.instance().start(this);即可在我们的Activity一开启的时候就启动SQLiteStudioService的实例,监听Androidxxx端口,等待远程的SQLiteStudio来连接。

4.3.3 SQLiteStudio连接手机实时调试

配置好App之后,只需要启动App,便可以在目录下创建好db文件,然后我们就可以在SQLiteStudio界面进行远程连接了。

添加的步骤和之前类似,不过数据类型方面我们选择Android SQLite,之后在选择db文件上,我们选择port forwarding,连接到某台手机的12121端口(也就是之前说的)SQLiteStudioService的实例监听的端口,之后就可以愉快的调试了。

5 食用荐语

以上就是关于AndroidSQlite的浅尝辄止的独家食用指南了,由于篇幅问题,只是简单的写了几个方面,不过相信大家也能懂得SQlite开发的基本流程了。当然,这只是SQlite这部分的第一篇文章,之后还有两篇文章会关注另外两个方面,包括SQlite的安全版本以及SQlite的实现源码分析。


独家食用指南系列|Android端SQLite的浅尝辄止相关推荐

  1. 独家食用指南系列|Android端SQLCipher的攻与防新编

    大家好,今天给大家的是本周技术拆解官的第二篇文章,主题依然是沿用上一篇文章的主题–Android端SQLite的"食用指南",上篇文章我们讲到了基本的SQLite的定义.使用方法以 ...

  2. 【环信IM集成指南】Android 端常见问题整理

    1.如何修改系统通知中的头像和用户名 系统通知是在主module中自己写的,demo中是AgreeMsgDelegate,InviteMsgDelegate,OtherMsgDelegate中去修改头 ...

  3. GPS定位系统(二)——Android端

    前言 GPS系列--Android端,github项目地址 tag: gps_mine Android移动端,主要是使用高德地图定位,后台上传定位信息,然后就是想办法尽量保活. 包括两个小功能:1.上 ...

  4. Android音视频学习系列(七) — 从0~1开发一款Android端播放器(支持多协议网络拉流本地文件)

    系列文章 Android音视频学习系列(一) - JNI从入门到精通 Android音视频学习系列(二) - 交叉编译动态库.静态库的入门 Android音视频学习系列(三) - Shell脚本入门 ...

  5. Android音视频学习系列(九) — Android端实现rtmp推流

    系列文章 Android音视频学习系列(一) - JNI从入门到精通 Android音视频学习系列(二) - 交叉编译动态库.静态库的入门 Android音视频学习系列(三) - Shell脚本入门 ...

  6. Android端实时音视频开发指南

    简介 yun2win-sdk-Android提供Android端实时音视频完整解决方案,方便客户快速集成实时音视频功能. SDK 提供的能力如下: 发起 加入 AVClient Channel AVM ...

  7. Android端IM应用中的@人功能实现:仿微博、QQ、微信,零入侵、高可扩展

    本文由"猫爸iYao"原创分享,感谢作者. 1.引言 最近有个需求:评论@人(没错,就是IM聊天或者微博APP里的@人功能),就像下图这样: ▲ 微信群聊界面里的@人功能  ▲ Q ...

  8. 微信小游戏直播在Android端的跨进程渲染推流实践

    本文由微信开发团队工程师"virwu"分享. 1.引言 近期,微信小游戏支持了视频号一键开播,将微信升级到最新版本,打开腾讯系小游戏(如跳一跳.欢乐斗地主等),在右上角菜单就可以看 ...

  9. 【无人机学习之QGroundControl】android端App初解4-遥控器通道

    █ [无人机学习之QGroundControl]android端App初解4-遥控器通道 █ 系列文章目录 提示:这里是收集了无人机的相关文章 [无人机学习]无人机基础知识 [无人机学习]Missio ...

最新文章

  1. zabbix安装文档
  2. SAP MM 创建退货类型的公司间STO,报错 -No delivery type for returns processing assigned to item 00010-
  3. linux下 /etc/profile、~/.bash_profile ~/.profile的执行过程
  4. 前端学习(2376):项目初始化
  5. 世界是你们的,也是我们的,但终究是他们的!致程序员
  6. vue联动切换搜索域
  7. func_get_args()获取一个函数的所有参数
  8. CSS练习_无限滚动
  9. Linux内核开发人员考虑剔除对更多老旧平台的处理器支持
  10. java 上传图片后没法立马显示出来_SpringMVC多个文件上传及上传后立即显示图片功能...
  11. 转搞网络的也可以很有柴的!
  12. js-格式化数字保留两位小数-带千分符
  13. 阶段1 语言基础+高级_1-3-Java语言高级_08-JDK8新特性_第1节 常用函数接口_16_常用的函数式接口_Function接口中练习-自定义函数模型拼接...
  14. printf()函数输出数据格式汇总
  15. PTT BBS-- 软件人的心路历程分享 (补习计算机、学习写程序、出书、出国、求职...这位前辈都经历过了)...
  16. 隐马尔可夫模型简单介绍
  17. DB9公头母头的定义
  18. 【重识云原生】第一章——不谋全局不足以谋一域
  19. 【Python第一课】课程介绍
  20. android 调用搜狗地图api,sogou地图API用法实例教程

热门文章

  1. 2023年中国数字孪生城市行业研究报告
  2. cad字体库大全2485种字体
  3. Vue报错:Root file specified for compilation Vetur(1261)
  4. iris配置https访问
  5. 克劳士比:有用的和可信赖的组织的核心是什么?
  6. R软件与RStudio安装(版本R-4.2.2)Windows10
  7. python实现中文的繁简转换
  8. XBOX360更新游戏封皮(FSD自制系统)
  9. div在屏幕中如何实现居中效果
  10. 百度云服务器网络检查,百度推出网站安全监测平台,为服务器提供安全漏洞扫描...