# AdbClient **Repository Path**: zyjun/adb-client ## Basic Information - **Project Name**: AdbClient - **Description**: 用adb管理手机的electron桌面应用 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-08-23 - **Last Updated**: 2023-09-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AdbClient 一个使用adb管理手机设备的工具应用 > 项目环境 > * 1.vue3 + vite + typescript > * 2.electron > * 3.node:14.18.2+ > * 4.依赖管理使用:yarn 参考文档:[搭建第一个 electron-vite 项目][搭建第一个 electron-vite 项目] **项目介绍** 按照`electron`项目的特性分为:`main`主进程,`preload`中间层,`render`渲染层 **实现的效果** ![](doc/adb-devices.png) ### 一、`main`主进程介绍 在`index.ts`入口文件里面有一个`createWindow()`方法是创建应用窗口的方法。 其他的`adb.ts`和`zip.ts`文件里面是给主进程注册的一些方法放在了`class`类里面方便管理和编写, 在代码最后会创建对应类的对象(主要为了执行类的构造方法)。 在`index.ts`入口文件中引入上面的`adb.ts`和`zip.ts`文件后就相当于执行了对象的构造方法即给主进程注册了一些方法。 [**Adb命令实现文档**](Adb命令实现文档.md) _`src/main/adb.ts`代码介绍:_ ``` import {app, dialog, ipcMain} from 'electron' const util = require("util"); const execPromise = util.promisify(require("child_process").exec); class AdbPlugin { adb_path: string | undefined; # 在vue页面中需要先调用checkAdbValidMain方法再调用其他方法,设置并检查adb路径没问题再执行其他方法 constructor() { //注册main进程的事件 ipcMain.handle('checkAdbValidMain', () => this.checkAdbValidMain()) ipcMain.handle('runAdbCommandMain', (event, para) => this.runAdbCommandMain(para)) } //检查adb环境是否正确 async checkAdbValidMain() { console.log("\n\ncheckAdbValidMain==") const isBuild = process.env.NODE_ENV === 'production'; let adb_path_dev = path.resolve(process.cwd(), 'doc', 'adb_win32', 'adb.exe') let adb_path_prod = path.resolve(process.cwd(), 'resources', 'adb_win32', 'adb.exe') this.adb_path = isBuild ? adb_path_prod : adb_path_dev ... return {platform, adbValid, adb_path: this.adb_path, adb_version}; } async runAdbCommandMain(para) { return await this._runAdb(para) } //执行adb命令 _runAdb(args) { let adbPath = localConfig.getItem('adbPath') args = `\"${adbPath}\" ${args}`; console.warn(`run: ${args}`); return execPromise(args); } } const adbPlugin = new AdbPlugin() ``` ### 二、`preload`中间层介绍 在入口文件`index.ts`中会给`window`定义一些属性。 在`adbApi.ts`和`zipApi.ts`文件中定义了`adbApi`对象及一些方法,主要是使用`ipcRenderer`调用`main`进程的方法。 在`index.ts`文件中引入上面的文件,并将`adbApi`对象和`zipApi`对象挂载到`window`上 _`src/preload/adbAPi.ts`代码介绍:_ ``` import {ipcRenderer} from 'electron'; // Custom APIs for renderer export const adbApi = { async checkAdbValidPreload() { return await ipcRenderer.invoke('checkAdbValidMain') }, async listDevicesPreload() { return await ipcRenderer.invoke('listDevicesMain') }, } ``` ### 三、`render`渲染层介绍 1.将所有需要调用`preload`中间层的方法都放在一个公共的文件`src/renderer/src/utils/plugin.ts`里面,方便方法参数的定义和使用等。 [**Adb组件实现介绍**](Adb组件实现介绍.md) _`src/render/src/utils/plugin.ts`代码介绍:_ ``` //adb功能 export const adbPlugin = new class { async checkAdbValidRender() { // @ts-ignore (define in dts) return await window.adbApi.checkAdbValidPreload() } async listDevicesRender() { // @ts-ignore (define in dts) return await window.adbApi.listDevicesPreload() } } ... ``` 2.具体在页面中调用的时候: _src/renderer/src/components/adb/DeviceList.vue代码介绍_ ``` const listDevices = async () => { ... let deviceList = await adbPlugin.listDevicesRender() console.log("listDevices=>", deviceList) state.deviceList = deviceList } ``` [搭建第一个 electron-vite 项目]:https://cn.electron-vite.org/guide/#%E6%90%AD%E5%BB%BA%E7%AC%AC%E4%B8%80%E4%B8%AA-electron-vite-%E9%A1%B9%E7%9B%AE