📜  如何在 Android 中访问 SQLite 数据库进行调试?

📅  最后修改于: 2022-05-13 01:58:44.356000             🧑  作者: Mango

如何在 Android 中访问 SQLite 数据库进行调试?

提供关系数据库管理系统的软件库称为 SQLite。它允许用户与 RDBMS 交互。 SQLite 中的 lite 在设置、数据库管理和所需资源方面表示轻量级。在 SQLite 中,数据库存储在单个文件中——这是一个区别于其他数据库引擎的属性。 SQLite 代码是开源的并且可以公开获得。它可以用于任何目的并且免费。它是全球部署最广泛的数据库,包括非常知名的项目,例如 Whatsapp。这是一个非常紧凑的库。库大小取决于目标平台和编译器设置,但即使启用所有功能后也可能小于 600KiB。 SQLite 对内存分配失败和磁盘 I/O 错误的响应非常优雅。 SQLite 中的所有事务都遵循 ACID 属性,即使它被系统崩溃甚至电源故障中断。所有交易均通过自动化测试进行验证。 SQLite 具有以下主要特性:自包含、无服务器、零配置、事务性。

SQLite 的优点

1. 自给自足

SQLite 的自包含属性意味着它需要操作系统(操作系统)或任何外部库的最低支持。这使得 SQLite 可以在任何类型的环境中使用,尤其是在 Android、iPhone、游戏机等嵌入式设备中。ANSI-C 用于开发 SQLite。它的源代码是一个大的 sqlite3.c 和它的头文件 sqlite3.h。如果有人想在他们的应用程序中启用 SQLite 的使用,他们只需将这些文件放到项目中并在代码中编译它们。

2.无服务器

MySQL、PostgreSQL等RDBMS需要单独的服务器进程来操作。需要访问数据库服务器的应用程序使用 TCP/IP 协议来发送和接收请求。这被称为客户端/服务器架构。下图解释了 RDBMS 客户端/服务器架构:

尽管 SQLite 不能以这种方式工作,但它不需要服务器来运行。在 SQLite 中,数据库与访问它的应用程序集成在一起。应用程序直接与数据库交互,读取和写入存储在磁盘上的数据库文件。下图解释了 SQLite 无服务器架构:

3.零配置

对于使用 SQLite,由于其无服务器架构,因此无需安装。不存在需要配置、启动和停止的服务器进程。此外,SQLite 不使用任何配置文件。

4. 交易

SQLite 中的所有事务都完全符合 ACID。这意味着所有查询和更改都是原子的、一致的、隔离的和持久的。即使发生应用程序崩溃、电源故障或操作系统崩溃等意外情况,事务中的所有更改或者完全发生或根本不发生。

Android中访问SQLite数据库进行调试的方法

方法 1:听诊器

它是来自 Facebook 的一个简单库,可用于轻松调试网络调用。使用 Stetho 时,无需在开发阶段添加日志,在发布时将其删除。不需要调试器。只需 3 个简单的步骤,我们就可以在 Chrome 浏览器上获取所有网络呼叫。从应用程序触发的所有网络请求,例如延迟、触发顺序、请求参数、响应数据。在 Stetho 中,除了网络检查之外,还有更多功能。

第 1 步:在 build.gradle 中添加依赖项

implementation 'com.facebook.stetho:stetho:1.5.1'
implementation 'com.facebook.stetho:stetho-okhttp3:1.5.1'                          
implementation 'com.facebook.stetho:stetho-urlconnection:1.5.1'

也可以添加 Javascript 控制台

implementation 'com.facebook.stetho:stetho-js-rhino:1.5.1'

第二步:用一行代码在应用类中初始化

public class MyApplication extends Application {
    public void onCreate() {
        super.OnCreate();

        if(BuildConfig.DEBUG) {

            Stetho.initializeWithDefaults(this)
        }
    }
}

在 AndroidManifest.xml 中注册类


       
        
  

第 3 步:启用网络检查

如果使用 3.x 版本的 OkHttp 库,那么可以使用拦截器系统将数据添加到现有堆栈,这也是自动的。这是启用网络检查的最直接的方法。

OkHttpClient.Builder()
  .addNetworkInterceptor(StethoInterceptor())
  .build()

拦截器是用于监视、重试和重写网络调用的机制。检查应用程序产生的每个呼叫的设置已完成,现在在 Chrome 浏览器中查看它们的步骤仍然存在。

第 4 步:设置 Chrome DevTool 以进行检查

Stetho 软件为应用程序提供的客户端或服务器协议,用于实现 Chrome DevTools 的集成。现在打开 Chrome 并连接具有该应用程序的设备。

Enter chrome://inspect in the URL bar of Chrome. 

点击回车,将显示连接的设备。

所有带有 USB 调试选项的设备都将显示在这里,设备上的所有应用程序都集成了听诊器。单击应用程序名称下方的检查,将打开一个新窗口,它以列表格式提供所有服务的概述以及所有详细信息。任何被触发的重复请求也将被显示。单击任何单个请求会显示三个不同的部分——标题、预览和响应。单击每个以查看各个部分。

第 5 步:使用 Stetho 进行数据库检查

单击检查后打开弹出窗口时,选择顶部的资源。左侧会出现很多选项,从中选择Web SQL,这是一个可以看到所有应用程序数据库的下拉菜单。通过单击任何表,它会显示其中包含所有数据的结构。也绝对不需要导出或导入东西。也可以执行查询以检查结果。单击 .db 文件,右侧将打开一个编辑器。根据需求编写查询。

方法二:使用外壳

  1. 在 Android 设备中启用开发者选项
  2. 启用 USB 调试
  3. 通过 USB 连接您的设备
  4. 当提示“允许 USB 调试”时。单击确定。

Unix Shell 可用于在设备上运行各种命令。 Android Debug Bridge(adb)提供对它的访问。通过运行 ADB shell 从命令提示符打开 ADB 的 shell。此 shell 可用于将数据库从应用程序目录中复制出来并将其粘贴到设备上的任何位置。

hell@device:/ $ mkdir /sdcard/data/
shell@device:/ $ run-as 
shell@device:/data/data/com.your.package $ cp databases/.db /sdcard/data/
shell@device:/data/data/com.your.package $ exit
shell@device:/ $ exit

现在可以从“/sdcard/data/”访问数据库文件。可以使用 ADB pull 将文件拉到本地主机:

adb pull /sdcard/data/.db

同样,您可以使用 ADB push 将文件推送到设备,从而更新数据库。只需反向执行这些步骤。

打开数据库

创建应用程序数据库的副本。现在需要一个兼容 SQLite 的数据库浏览器来打开数据库。 SQLite 数据库浏览器是浏览和编辑 SQLite 数据库文件的最佳工具之一。它是适用于 Windows、macOS 和 Linux 的开源软件。

方法 3:使用 Android 调试数据库 (ADD)

Android调试数据库完成的任务:

  • 查看所有数据库。
  • 查看应用程序中使用的共享首选项中的所有数据。
  • 在给定数据库上运行任何 SQL 查询以更新和删除数据。
  • 直接编辑数据库值。
  • 直接编辑共享首选项。
  • 直接在数据库中添加一行。
  • 直接在共享首选项中添加一个键值。
  • 删除数据库行和共享首选项。
  • 在数据中搜索。
  • 对数据进行排序。
  • 导出数据库。
  • 检查数据库版本。
  • 下载数据库

先决条件:

在应用程序中实现Android调试数据库库之前,有几点需要注意

  1. Android 设备和笔记本电脑应该在同一个网络上。 (局域网或无线网络)
  2. 如果通过 USB 使用手机,在终端执行以下命令
adb forward tcp:8080 tcp:8080

如果您需要使用 8080 以外的任何其他端口,请在 build.gradle 文件中进行以下更改

debug {
   resValue("string", "PORT_NUMBER", "8081")
}

使用 Android 调试数据库库

添加以下依赖项以开始在应用程序中使用 Android 调试数据库。在 build.gradle 文件中添加此依赖项。

dependencies {
   ...
   debugImplementation 'com.amitshekhar.android:debug-db:1.0.6'
   ...
}

现在运行应用程序,您将在 logcat 中看到与下面给出的条目类似的条目。

D/DebugDB: 

Open http://XXX.XXX.X.XXX:8080 in your browser

要从代码中获取调试地址 URL,只需调用以下方法:

DebugDB.getAddressLog();

在浏览器中打开 URL,将打开一个界面,显示与数据库和共享首选项相关的所有详细信息。

添加。只需分别单击添加、删除或编辑按钮,即可轻松完成对表中存在的值的删除或编辑操作

任何数据库操作也可以使用 SQL 查询来完成,只需在查询部分输入查询,Android 调试数据库将完成剩下的工作。

在 Toast 中获取调试地址 URL

调试地址也可以使用 Toast 消息显示。可以使用以下代码完成。

public static void showDebugDBAddressLogToast(Context context) {
   if (BuildConfig.DEBUG) {
      try {
           Class debugDB = Class.forName("com.amitshekhar.DebugDB");
           Method getAddressLog = debugDB.getMethod("getAddressLog");
           Object value = getAddressLog.invoke(null);
           Toast.makeText(context, (String) value, Toast.LENGTH_LONG).show();
      } catch (Exception ignore) {

      }
   }
}

添加自定义数据库文件

Android 数据库库是自动初始化的,要调试自定义数据库文件,添加以下方法并调用它。

public static void setCustomDatabaseFiles(Context context) {
   if (BuildConfig.DEBUG) {
       try {
           Class debugDB = Class.forName("com.amitshekhar.DebugDB");
           Class[] argTypes = new Class[]{HashMap.class};
           Method setCustomDatabaseFiles = debugDB.getMethod("setCustomDatabaseFiles", argTypes);
           HashMap> customDatabaseFiles = new HashMap<>();
           // set your custom database files
           customDatabaseFiles.put(ExtTestDBHelper.DATABASE_NAME,
                   new Pair<>(new File(context.getFilesDir() + "/" + ExtTestDBHelper.DIR_NAME +
                                                   "/" + ExtTestDBHelper.DATABASE_NAME), ""));
           setCustomDatabaseFiles.invoke(null, customDatabaseFiles);
       } catch (Exception ignore) {

       }
   }
}

SQLite 的缺点

SQLite 的标志性特性,使它与其他的非常不同,是它的可移植性。不幸的是,当许多不同的用户同时更新同一个表时,它是一个糟糕的选择。这是一条黄金法则,为了保持数据的完整性,一次只有一个用户可以写入文件。由于使 SQLite 可访问的功能,还需要做更多的工作来确保私有数据的安全性。 SQLite 与其他数据库系统完全不同,它限制了其他关系数据库系统提供的许多高级功能。 SQLite 不验证数据类型。 SQLite 允许用户将任何类型的数据存储到任何列中,而许多其他数据库软件会拒绝不符合表模式的数据。

SQLite 创建模式,限制每列中的数据类型,但不强制执行。下面的示例显示 id 列要存储整数,name 列要存储文本,age 列要存储整数:

CREATE TABLE celebs (
 id INTEGER,
 name TEXT,
 age INTEGER
);

SQLite 永远不会拒绝不同数据类型的值。我们可能会在列中插入错误的数据类型。在同一列中存储不同的数据类型是不可接受的行为,可能导致无法修复的错误,因此需要对特定列中的数据保持一致,即使 SQLite 不会强制执行。