美文网首页
Android-Debug-Database调试手机或者模拟器已

Android-Debug-Database调试手机或者模拟器已

作者: 全球顶尖伪极客 | 来源:发表于2018-08-28 15:27 被阅读0次

android系统中现在android studio3.+版本上可通过Device File Explorer下,选择data/data/包名下的databases查找对应的数据库并导出查看。
现我们可以采用 Android-Debug-DatabaseGitHub上的此库对数据库、sharedprefrence进行增删改查等操作。

Android Debug Database可以做什么呢?

  • 查看所有数据库
  • 查看应用程序中使用的shared preferences所有数据
  • 在给定数据库上运行任何sql查询以更新和删除数据
  • 直接编辑数据库值。
  • 直接编辑shared preferences
    ....

1.接入方式build.gradle

debugImplementation 'com.amitshekhar.android:debug-db:1.0.4'

2.x android studio

debugCompile 'com.amitshekhar.android:debug-db:1.0.4'

可能会存在can't find xxx or failed to resolve xxx可在project 下的 build.gradle加入

 jcenter()
 maven {
            url "https://jitpack.io"
        }

Android 添加依赖failed to resolve xxxx库解决方案

2.真机调试

Terminal终端下运行adb forward tcp:8080 tcp:8080,经测算真机或者模拟器均要启动命令开启端口才生效。以下分析估测为socket请求原因。
如果APP运行在手机上,此时保证手机和浏览器链接的是同一局域网下的WiFi,可输入localhost:8080或者加上代码Toast提示手机此时的ip地址、或者最直接Log.i打印ip地址,点击即可到达浏览器。

  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);
                Log.i("DebugDB_IPAddress", "Debug DB 下的IP地址"+value);
                Toast.makeText(context, (String) value, Toast.LENGTH_LONG).show();
            } catch (Exception ignore) {

            }
        }
    }
DebugDB_IPAddress: Debug DB 下的IP地址Open http://172.20.188.2:8080 in your browser

http://localhost:8080/

3.模拟器调试:

Terminal终端下运行adb forward tcp:8080 tcp:8080
如果端口冲突可在gradle.build下加入

 buildTypes {
        debug {
            //更改此处端口
            resValue("string", "PORT_NUMBER", "8088")
            resValue("string", "DB_PASSWORD_PERSON", "a_password")
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

adb forward tcp:8088 tcp:8088

debug-db库中的DebugDB.java文件下开启了一个线程,并不断以socket形式处理浏览器发过来的请求,判断socket发送过来的请求内容进行处理返回不通的结果。

  public static void initialize(Context context) {
        int portNumber;

        try {
            portNumber = Integer.valueOf(context.getString(R.string.PORT_NUMBER));
        } catch (NumberFormatException ex) {
            Log.e(TAG, "PORT_NUMBER should be integer", ex);
            portNumber = DEFAULT_PORT;
            Log.i(TAG, "Using Default port : " + DEFAULT_PORT);
        }

        clientServer = new ClientServer(context, portNumber);
        clientServer.start();//开启线程
        addressLog = NetworkUtils.getAddressLog(context, portNumber);
        Log.d(TAG, addressLog);
    }

public class ClientServer implements Runnable {
    ...

    public ClientServer(Context context, int port) {
        mRequestHandler = new RequestHandler(context);
        mPort = port;
    }

    public void start() {
        mIsRunning = true;
        new Thread(this).start();
    }
    ...

    @Override
    public void run() {
        try {
            mServerSocket = new ServerSocket(mPort);
            while (mIsRunning) {
                Socket socket = mServerSocket.accept();
                mRequestHandler.handle(socket);
                socket.close();
            }
        } catch (SocketException e) {
            // The server was stopped; ignore.
        } catch (IOException e) {
            Log.e(TAG, "Web server error.", e);
        } catch (Exception ignore) {
            Log.e(TAG, "Exception.", ignore);
        }
    }
    ...
}


public class RequestHandler {
    ...
    public RequestHandler(Context context) {
        mContext = context;
        mAssets = context.getResources().getAssets();
        mGson = new GsonBuilder().serializeNulls().create();
    }

    public void handle(Socket socket) throws IOException {
        BufferedReader reader = null;
        PrintStream output = null;
        try {
            String route = null;

            // Read HTTP headers and parse out the route.
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line;
            while (!TextUtils.isEmpty(line = reader.readLine())) {
                if (line.startsWith("GET /")) {
                    int start = line.indexOf('/') + 1;
                    int end = line.indexOf(' ', start);
                    route = line.substring(start, end);
                    break;
                }
            }

            // Output stream that we send the response to
            output = new PrintStream(socket.getOutputStream());

            if (route == null || route.isEmpty()) {
                route = "index.html";
            }

            byte[] bytes;

            if (route.startsWith("getDbList")) {
                final String response = getDBListResponse();
                bytes = response.getBytes();
            } else if (route.startsWith("getAllDataFromTheTable")) {
                final String response = getAllDataFromTheTableResponse(route);
                bytes = response.getBytes();
            } else if (route.startsWith("getTableList")) {
                final String response = getTableListResponse(route);
                bytes = response.getBytes();
            } else if (route.startsWith("addTableData")) {
                final String response = addTableDataAndGetResponse(route);
                bytes = response.getBytes();
            } else if (route.startsWith("updateTableData")) {
                final String response = updateTableDataAndGetResponse(route);
                bytes = response.getBytes();
            } else if (route.startsWith("deleteTableData")) {
                final String response = deleteTableDataAndGetResponse(route);
                bytes = response.getBytes();
            } else if (route.startsWith("query")) {
                final String response = executeQueryAndGetResponse(route);
                bytes = response.getBytes();
            } else if (route.startsWith("downloadDb")) {
                bytes = Utils.getDatabase(mSelectedDatabase, mDatabaseFiles);
            } else {
                bytes = Utils.loadContent(route, mAssets);
            }

            if (null == bytes) {
                writeServerError(output);
                return;
            }

            // Send out the content.
            output.println("HTTP/1.0 200 OK");
            output.println("Content-Type: " + Utils.detectMimeType(route));

            if (route.startsWith("downloadDb")) {
                output.println("Content-Disposition: attachment; filename=" + mSelectedDatabase);
            } else {
                output.println("Content-Length: " + bytes.length);
            }
            output.println();
            output.write(bytes);
            output.flush();
        } finally {
            try {
                if (null != output) {
                    output.close();
                }
                if (null != reader) {
                    reader.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    ...
}

debug-db将有交互性的html发送给浏览器。

image.png

出现两个项目A、B都公用一个端口,A已开启端口,adb forward tcp:8080 tcp:8080B也想用已开启的端口的服务,那么可以通过关闭A,再开启B。在DebugBD中可以调用DebugDB.shutDown()

public class DebugDB {
    ...
    public static void shutDown() {
        if (clientServer != null) {
            clientServer.stop();
            clientServer = null;
        }
    }
    ...
image.png

端口查看:netstat -aon|findstr "8080"

D:\androidstudio\work\WDSGQMSTrunk>netstat -aon|findstr "8080"
  TCP    127.0.0.1:8080         0.0.0.0:0              LISTENING       8468
  TCP    192.168.101.50:58779   223.167.104.149:8080   ESTABLISHED     11388

image.png
image.png
记得操作后重启APP有时候不会生效。
netstat -ano | findstr "8080"(adb默认端口5037,现查找的为8080)

tasklist /fi "PID eq 8468"(找出来占端口的是谁)

taskkill /pid 8468 /f 除掉

adb默认的情况netstat -ano | findstr "5037"可查看占用情况
netstat -ano查看全部端口情况。
实在难得操作直接adb kill-serveradb start -server 最终还是要重启App让其重新启动线程生效。

Android ADB命令参考

相关文章

网友评论

      本文标题:Android-Debug-Database调试手机或者模拟器已

      本文链接:https://www.haomeiwen.com/subject/kqzfwftx.html