ADB (Android Debug Bridge) detailed explanation

Whether you are doing App crawler automation, reverse analysis, or Android native/cross-end development, ADB (Android Debug Bridge) is a "mobile Swiss Army Knife". It allows you to control your phone like a local command line: install applications, transfer files, capture logs, screenshots, port forwarding...all done with one command.

This article starts from scratch and explains the core scenarios of device connection, file transfer, application management, and Python automation in the most straightforward language. This eliminates the need for you to look up the commands piecemeal, and you can get started after reading them.


1. Device Management: Connection is the first step

Newbies are most likely to get stuck in "unauthorized" (unauthorized), "offline" or the device list is blank. Let’s first explain USB debugging, WiFi wireless connection, and common problem troubleshooting at once.

1.1 Turn on USB debugging (key points to avoid pitfalls)

Whether using USB or WiFi, the phone must first pop up the "Allow USB debugging" authorization box and confirm it. The configuration process only needs to be done once:

  1. Data cable: You must use a "charging + data transmission two-in-one" data cable. A pure charging cable cannot be recognized.
  2. Developer Options: Go to "Settings → About Phone" and click Build Number 7 times until it prompts "Developer Options Turned On".
  3. Turn on debugging: Return to "Settings → System (or more settings) → Developer Options", find and enable the following two options:
  • USB Debugging
  • USB Debugging (Security Settings) (some systems call it "USB Installation" or "Cancel Authorization Blank", etc.)
  1. Pop-up box confirmation: After connecting to the computer with a data cable, the phone will pop up the "Allow USB debugging?" dialog box. Be sure to check "Always allow the use of this computer for debugging", and then click "OK".

If the pop-up box does not pop up, or it displaysunauthorized, use the following "universal restart method":

# 停止 ADB 服务(能解决绝大多数授权和离线问题)
adb kill-server
# 重新启动 ADB 服务
adb start-server

Afterwards, re-plug and unplug the data cable or reconnect to WiFi, and the pop-up box will usually appear.

1.2 Basic connection check

After connecting the device, first useadb devicesConfirm status:

# 查看所有已连接设备的 ID 和状态
# device   → 已授权,可以操作
# unauthorized → 未授权,需要手机上确认
# offline  → 离线,一般是服务挂了或调试开关关闭
adb devices

# 只提取正常设备的 ID(写脚本时常用)
adb devices -l | awk 'NR>1 && /device/ && !/offline/ {print $1}'

1.3 WiFi wireless debugging (liberating data lines)

Wireless debugging can be enabled when the mobile phone and computer are connected to the same LAN (under the same WiFi or router), and there is no need to plug in the wires in the future.

Operation steps:

# 1. 先通过 USB 连上设备,确认 adb devices 显示 device
# 2. 让手机监听 TCP/IP 端口(默认 5555)
adb tcpip 5555

# 3. 查看手机的局域网 IP 地址(任选一种命令)
# 方法 A:最通用,绝大多数机型可用
adb shell getprop dhcp.wlan0.ipaddress
# 方法 B:查看网卡信息,试试 wlan0 / eth0 / rmnet_data0
adb shell ifconfig wlan0
# 方法 C:Android 10 及以上更精准
adb shell cmd connectivity wifi status | grep "IpAddress"

# 4. 用 IP + 端口连接(替换成你手机的 IP)
adb connect 192.168.1.100:5555

# 5. 拔掉 USB 线,再次运行 adb devices 确认设备状态为 device

After the connection is successful, as long as the mobile phone and computer are in the same LAN, each timeadb connect <手机IP>:5555You can connect.

Tips: If the WiFi connection cannot be connected, you can firstadb kill-server && adb start-serverTry again. In addition, the 5555 port will be closed after some systems are restarted and need to be activated again with a USB cable.


2. File transfer: high-speed mutual transfer without compromising image quality

Are you still using WeChat/QQ to transfer files? Not only is the image quality compressed, but the speed is also slower. ADB files are transferred via data cable or LAN, and the speed depends on the bandwidth. It is very suitable for transferring APK, logs, and test data.

Commonly used commands:

# 将本地文件推送到手机
# /sdcard/ 开头是用户公共目录,不需要 root
adb push ./test_apk.apk /sdcard/

# 整个文件夹递归推送(-r)
adb push -r ./crawler_temp /sdcard/crawler_backup/

# 从手机拉取文件到本地
adb pull /sdcard/logcat_latest.txt ./
adb pull -r /sdcard/crawler_backup/ ./local_data/

# 增量同步(只传输有变化的文件,比全量 cp 更快)
adb sync          # 同步 /sdcard 等公共分区
adb sync /system  # 同步系统分区(需 root)

3. Application Control: Basic Skills of App Crawler

The first step of the crawler is to control the application: installation, uninstallation, obtaining package name, startup, forced stop, all of which ADB can perfectly support.

3.1 Installation and Uninstallation

# 安装 APK
adb install ./test_apk.apk          # 普通安装
adb install -r ./test_apk_v2.apk    # 覆盖安装(保留数据)
adb install -d ./test_apk_v1.apk    # 降级安装(签名要相同)
adb install -s ./test_apk.apk       # 安装到 SD 卡(旧机型)

# 卸载应用
adb uninstall com.example.testapp       # 普通卸载
adb uninstall -k com.example.testapp    # 彻底卸载(删除所有数据)

In actual use,install -randuninstall -kThe most commonly used, the former is used for version iteration, and the latter is used to reset the application environment.

3.2 Query application information (find package name, startup page)

# 列出所有安装的包
adb shell pm list packages        # 全部(系统 + 第三方)
adb shell pm list packages -3     # 只看第三方(爬虫最常用)
adb shell pm list packages -s     # 只看系统应用
adb shell pm list packages -f     # 显示包对应的 APK 路径(方便逆向分析)

# 查看某个应用的详细信息
adb shell dumpsys package com.example.testapp

# 从 dumpsys 中快速提取关键信息
# 版本名
adb shell dumpsys package com.example.testapp | grep versionName
# 版本号
adb shell dumpsys package com.example.testapp | grep versionCode
# 启动 Activity(找带 LAUNCHER 的)
adb shell dumpsys package com.example.testapp | grep -A 5 "android.intent.category.LAUNCHER"

After getting the package name and starting the Activity, you can accurately control the application startup, which is more stable than using monkey.

3.3 Starting and stopping applications

# 强制停止(彻底杀掉进程)
adb shell am force-stop com.example.testapp

# 启动应用
# 方法一:指定组件名(最推荐)
adb shell am start -n com.example.testapp/.MainActivity

# 方法二:用 monkey 模拟点击图标(不知道启动 Activity 时备用)
adb shell monkey -p com.example.testapp -c android.intent.category.LAUNCHER 1

After starting the application, you can start automated work with screenshots, screen recordings, logs, etc.


4. Python automated control: batch operations free your hands

A single command is too inefficient. For example, if you want to install the same application on 10 mobile phones, or automatically take screenshots every 5 seconds, typing commands manually is too error-prone. Use Python to encapsulate ADB commands into classes, which can not only be processed in batches, but can also be flexibly integrated into the crawler process.

The following is a lightweight ADB controller based on Python’s ownsubprocessModule, no need to install any third-party libraries, just ready to use.

import subprocess
import time
import os
from typing import Optional, List

class LightADB:
    """轻量级 ADB 控制器,专注 App 爬虫 / 日常自动化"""

    def __init__(self, device_id: Optional[str] = None, timeout: int = 30):
        self.device_id = device_id
        self.timeout = timeout
        self.available_devices = self._fetch_devices()
        self.current_device = self._select_current_device()
        print(f"✅ ADB 初始化完成,当前操作设备: {self.current_device}")

    def _fetch_devices(self) -> List[str]:
        """获取所有已授权在线设备的 ID"""
        try:
            result = subprocess.run(
                ['adb', 'devices'],
                capture_output=True, text=True, timeout=self.timeout
            )
            raw_lines = result.stdout.strip().split('\n')[1:]
            return [
                line.split('\t')[0]
                for line in raw_lines
                if '\tdevice' in line
            ]
        except subprocess.TimeoutExpired:
            print("⚠️ ADB 命令超时,请检查服务是否正常")
            return []
        except Exception as e:
            print(f"❌ 获取设备列表失败: {e}")
            return []

    def _select_current_device(self) -> str:
        """选择当前要操作的设备"""
        if not self.available_devices:
            raise RuntimeError("❌ 未找到可用 ADB 设备,请检查连接和授权。")
        if self.device_id and self.device_id in self.available_devices:
            return self.device_id
        return self.available_devices[0]

    def _exec_cmd(self, cmd_list: List[str]) -> str:
        """执行 adb -s <serial> <cmd> 命令并返回输出"""
        full_cmd = ['adb', '-s', self.current_device] + cmd_list
        try:
            result = subprocess.run(
                full_cmd,
                capture_output=True, text=True, timeout=self.timeout
            )
            if result.returncode != 0:
                print(f"⚠️ 命令执行失败: {' '.join(full_cmd)}\n{result.stderr.strip()}")
                return ""
            return result.stdout.strip()
        except Exception as e:
            print(f"❌ 命令异常: {e}")
            return ""

    # ---------- 常用操作方法 ----------
    def get_third_packages(self) -> List[str]:
        """获取所有第三方应用包名"""
        output = self._exec_cmd(['shell', 'pm', 'list', 'packages', '-3'])
        return [line.split(':')[1] for line in output.split('\n') if line.strip()]

    def capture_screen(self, save_dir: str = "./adb_screenshots") -> Optional[str]:
        """
        手机截屏并自动拉取到本地
        :param save_dir: 本地保存目录,会自动创建
        :return: 成功时返回图片路径,失败返回 None
        """
        os.makedirs(save_dir, exist_ok=True)
        timestamp = int(time.time())
        temp_phone_path = f"/sdcard/adb_temp_{timestamp}.png"
        local_path = os.path.join(save_dir, f"screen_{timestamp}.png")

        # 1. 手机端截图
        self._exec_cmd(['shell', 'screencap', temp_phone_path])
        # 2. 拉取到电脑
        pull_res = self._exec_cmd(['pull', temp_phone_path, local_path])
        # 3. 删除手机临时文件
        self._exec_cmd(['shell', 'rm', temp_phone_path])

        if "pulled" in pull_res.lower():
            print(f"✅ 截屏已保存: {local_path}")
            return local_path
        return None

# ================= 使用示例 =================
if __name__ == "__main__":
    try:
        adb = LightADB()

        # 1. 查看前 3 个第三方应用
        packages = adb.get_third_packages()[:3]
        print(f"📱 前 3 个第三方应用: {packages}")

        # 2. 每隔 2 秒截屏一次,连续截 3 次
        for i in range(3):
            adb.capture_screen()
            if i < 2:
                time.sleep(2)

    except Exception as e:
        print(f"❌ 示例运行失败: {e}")

This simplest controller covers high-frequency operations such as connection management, package name acquisition, and screenshots. You can continue to expand according to your needs: for example, addtapswipeinputand other methods to realize automated clicking, sliding and text input.


5. Add a few practical tips

5.1 Port forwarding

Sometimes we need to map a local service on the mobile phone to the computer. For example, if the mobile phone runs an HTTP API on port 5000, you can use port forwarding to pass it on the computer.localhost:6000direct access.

# 将电脑 6000 端口转发到手机的 5000 端口
adb forward tcp:6000 tcp:5000

# 查看当前所有转发规则
adb forward --list

# 取消所有转发
adb forward --remove-all

This is very useful when debugging remote interfaces and proxy man-in-the-middle packet capture.

5.2 Clear the log buffer

When crawling or debugging, too many old logs can interfere with analysis. Clear it first and then start capturing the logs. The result is much cleaner:

# 清空所有日志缓冲区
adb logcat -c

Use lateradb logcat -s YOUR_TAGIt is very refreshing to capture the logs with specified tags.


ADB is the cornerstone of mobile debugging. The above commands and Python packaging are sufficient to support most app crawling and automation needs. If you encounter more complex UI interactions (such as needing to click buttons, slide lists, and enter text), you can further combineuiautomator2orAppiumThis kind of high-level framework, but the bottom layer is still inseparable from the stable connection and basic operations of ADB.

I hope this detailed explanation can help you successfully overcome the mobile automation level.