Debugging SQLite with adb

前端之家收集整理的这篇文章主要介绍了Debugging SQLite with adb前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

有的时候写完关于sqlite的操作逻辑,需要进行验证。最笨的就是处理完之后通过代码读取内容打印到logcat中查看。但是,可以使用adb把db文件读取到本地,然后使用sqlite对应的管理工具打开查看不更方便吗?下面就会介绍如何实现这种操作。

注意:下面所有操作假设设备已经具有root权限,否则没有权限读取这些数据

存储位置

一个应用的db文件存储在/data/data/your package name/databases/下面。

adb介绍

Android Debug Bridge是Google提供的调试工具。

上图是adb的基本结构。adb存在三种成员:

  • client:这个是在开发的机器上面,可以具有多个client,用于请求server操作设备。
  • server:这个也是在开发的机器上面,用于管理client和各个设备上的daemon之间的数据交流,只有一个实例。当一个client启动的时候,如果不存在server,那么则会启动server,其他则不处理。
  • daemon:这个在设备(包括实际的模拟器)上面,是设备上后台运行的进程。

从上面的图也可以看出来,adb是client-server模式的。

只有在设备打开开发者选项中的调试模式的时候adb才会有作用

常见命令
  1. adb [-d|-e|-s [serial number]] shell [command]

    这条命令用于打开特定设备的shell。其中-d表示连接实体设备,-e表示模拟器,-s表示连接特定的设备,使用后面的serial number来确定设备。如果只有一台连接设备的情况下不需要指明设备编号,adb会自动指定。如果是多台设备必须指明serial number最后的command是要直接执行的命令,如果没有则直接进入shell。

  2. adb pull <remote> <local>

    这条命令用于把设备上的文件复制到本地。

  3. adb push <local> <remote>

    这条命令用于把本地的文件复制到设备上面。

  4. adb devices

    这条命令用于查看当前连接设备的情况,包括设备的serial number以及状态(offline和online)。

  5. adb install <local>

    这条命令用于在设备上安装apk文件

@H_403_81@常用Linux命令

因为进入shell之后就是操作Android,由于Android是基于Linux内核,因此需要使用几个常用的Linux命令。

  1. ls

    用于查看当前目录下面的文件文件夹情况。

  2. cd

    用于切换目录,其中cd..用于退到上一级目录。

  3. cat

复制sqlite文件到本地

具体命令如下:

adb -d shell 'run-as your_package_name cat /data/data/your_package_name/databases/your_db_file_name > /sdcard/your_db_file_name'
adb pull /sdcard/your_db_file_name location_of_file_in_your_machine

Starting from API level 8 (Android 2.2),if you build the application as debuggable,you can use the shell run-as command to run a command or executable as a specific user/application or just switch to the UID of your application so you can access its data directory.

  • 从API 8开始需要使用run-as命令加上特定的包名或者应用的UID之后,才能获取到data目录下的数据。这个就是上面的命令中使用run-as命令的原因。

  • 使用pull命令直接复制db文件会被拒绝,因此需要先用cat命令把对应的db文件复制到sdcard上面,然后再使用pull命令把文件复制到本地。

具体说明可以参阅:Debugging sqlite database on the device

打开cmd,切换到your_sdk_directory/platform-tools下面,然后执行上面两个命令就可以把db文件复制到本地特定的位置了。

脚本实现复制

上面的命令已经很简单了,但是如果以后想使用的话,就需要自己一点一点去改命令中的参数,但是如果可以使用代码实现输入对应的参数然后自动执行就好了,下面的代码就是实现了这个功能

import java.util.Scanner;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.File;

/** * @author jy.wang */
public class AdbPullDatabase{
    public static void main(String args[]){

        Scanner sin = new Scanner(System.in);
        System.out.println("Please input adb directory:");
        final String adbDirectory =sin.nextLine().trim();
        System.out.println();
        System.out.print("Please input package name:");
        final String packageName = sin.nextLine().trim().split("\\s+")[0];
        System.out.println();
        System.out.print("Please input database name:");
        final String dbName = sin.nextLine().trim().split("\\s+")[0];
        System.out.println();
        System.out.print("Please input database location:");
        final String dbLocation = sin.nextLine().split("\\s+")[0];
        System.out.println();
        sin.close();

        try{
            final String changeDirectory = "cd /d "+adbDirectory;
            final String saveToSdCardCommand = "adb -d shell 'run-as "+packageName+" cat /data/data/"+packageName+"/databases/"+dbName+" > /sdcard/"+dbName+"'";
            final String pullDBCommand = "adb pull /sdcard/"+dbName+" "+dbLocation;
            File file = new File("command.bat");
            BufferedWriter writer = new BufferedWriter(new FileWriter(file));
            writer.write(changeDirectory,0,changeDirectory.length());
            writer.newLine();
            writer.write(saveToSdCardCommand,saveToSdCardCommand.length());
            writer.newLine();
            writer.write(pullDBCommand,pullDBCommand.length());
            writer.close();
            Runtime.getRuntime().exec("cmd /c start "+file.getAbsolutePath());
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

其中使用了bat批处理文件实现java调用多条cmd命令的技巧,具体可以参阅Java中调用多条cmd命令

猜你在找的Sqlite相关文章