鸿蒙开发效率手册

2,536 阅读7分钟

本文为稀土掘金技术社区首发签约文章,30天内禁止转载,30天后未获授权禁止转载,侵权必究!

本手册长期维护,持续更新中...

一. 数据持久化

1.1 用户首选项Preferences (@ohos.data.preferences)

Preferences 提供 Key-Value 键值型的数据处理能力,实例代码如下:

let options: dataPreferences.Options = { name: 'myStore' };
preferences = dataPreferences.getPreferencesSync(context, options);
preferences.putSync('startup', 'auto');//写数据
preferences.getSync('startup', 'default');//读数据
preferences.deleteSync('startup');//删除数据

//将当前Preferences实例的数据异步存储到用户首选项持久化文件中。
preferences.flush((error: BusinessError) => {
  if (error) {
    console.log(`持久化失败 error = ${JSON.stringify(error)}`);
    return;
  }
  console.log("持久化成功");
});
核心API说明:
  • getPreferencesSync(context, options):同步获取Preferences实例。options包含name属性,用于指定存储的名称。
  • putSync(key, value):同步存储键值对到Preferences中,使用flush方法确保数据持久化。
  • getSync(key, defaultValue):同步读取指定键的值,如果不存在则返回defaultValue
  • deleteSync(key):同步删除指定键的值。
  • flush(callback):异步将Preferences实例中的数据存储到持久化文件中。需要注意的是,putSync等方法只是修改了内存中的实例,需要调用flush来持久化数据。
使用场景:
  • 用户设置:存储用户的偏好设置,例如启动选项、主题设置等。
  • 应用配置:保存应用运行时的一些配置信息,如最后访问的页面等。
开发注意事项:
  • 一定要在putSync之后调用flush,否则只是修改了内存中的 preferences 实例,数据不会被持久化。
  • flush方法是异步的,建议在回调中处理持久化成功或失败的逻辑。

1.2 键值型数据库(@ohos.data.distributedKVStore)

SQLite 是鸿蒙操作系统中用于结构化数据存储的数据库。以下是一个创建和使用SQLite数据库的示例:

第一步:获取 KVManager 实例

// 导入模块
import distributedKVStore from '@ohos.data.distributedKVStore';

let context = this.context;
const kvManagerConfig: distributedKVStore.KVManagerConfig = {
  context: context,
  bundleName: 'com.example.datamanagertest'
};
try {
  // 创建KVManager实例
  kvManager = distributedKVStore.createKVManager(kvManagerConfig);
  console.info('Succeeded in creating KVManager.');
  // 继续创建获取数据库
} catch (e) {
  let error = e as BusinessError;
  console.error(`Failed to create KVManager. Code:${error.code},message:${error.message}`);
}

第二步:创建并获取键值数据库

let kvStore: distributedKVStore.SingleKVStore | undefined = undefined;
try {
  const options: distributedKVStore.Options = {
    createIfMissing: true,
    encrypt: false,
    backup: false,
    autoSync: false,
    // kvStoreType不填时,默认创建多设备协同数据库
    kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,
    // 多设备协同数据库:kvStoreType: distributedKVStore.KVStoreType.DEVICE_COLLABORATION,
    securityLevel: distributedKVStore.SecurityLevel.S1
  };
  kvManager.getKVStore<distributedKVStore.SingleKVStore>('storeId', options, (err, store: distributedKVStore.SingleKVStore) => {
    if (err) {
      console.error(`Failed to get KVStore: Code:${err.code},message:${err.message}`);
      return;
    }
    console.info('Succeeded in getting KVStore.');
    kvStore = store;
    // 请确保获取到键值数据库实例后,再进行相关数据操作
  });
} catch (e) {
  let error = e as BusinessError;
  console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`);
}
if (kvStore !== undefined) {
  kvStore = kvStore as distributedKVStore.SingleKVStore;
    //进行后续操作
    //...
}

第三步:操作数据库

const KEY_TEST_STRING_ELEMENT = 'key_test_string';
const VALUE_TEST_STRING_ELEMENT = 'value_test_string';

//新增
kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, (err) => {});
//删除
kvStore.delete(KEY_TEST_STRING_ELEMENT, (err) => {});
//查找
kvStore.get(KEY_TEST_STRING_ELEMENT, (err, data) => {});

1.3 关系型数据库(@ohos.data.relationalStore)

基于SQLite组件,适用于存储包含复杂关系数据的场景

第一步:获取RdbStore

import relationalStore from '@ohos.data.relationalStore'; // 导入模块 


class EntryAbility extends UIAbility {
  onWindowStageCreate(windowStage: window.WindowStage) {
    const STORE_CONFIG :relationalStore.StoreConfig= {
      name: 'RdbTest.db', // 数据库文件名
      securityLevel: relationalStore.SecurityLevel.S1, // 数据库安全级别
      encrypt: false, // 可选参数,指定数据库是否加密,默认不加密
      dataGroupId: 'dataGroupID', // 可选参数表示为应用组ID,需向应用市场获取。指定在此Id对应的沙箱路径下创建实例,不填时,默认在本应用沙箱目录下创建。
      customDir: 'customDir/subCustomDir' // 可选参数,数据库自定义路径。数据库将在如下的目录结构中被创建:context.databaseDir + '/rdb/' + customDir,其中context.databaseDir是应用沙箱对应的路径,'/rdb/'表示创建的是关系型数据库,customDir表示自定义的路径。当此参数不填时,默认在本应用沙箱目录下创建RdbStore实例。
    };

    // 判断数据库版本,如果不匹配则需进行升降级操作
    // 假设当前数据库版本为3,表结构:EMPLOYEE (NAME, AGE, SALARY, CODES)
    const SQL_CREATE_TABLE = 'CREATE TABLE IF NOT EXISTS EMPLOYEE (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT NOT NULL, AGE INTEGER, SALARY REAL, CODES BLOB)'; // 建表Sql语句

    relationalStore.getRdbStore(this.context, STORE_CONFIG, (err, store) => {
      if (err) {
        console.error(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
        return;
      }
      console.info('Succeeded in getting RdbStore.');

      // 当数据库创建时,数据库默认版本为0
      if (store.version === 0) {
        store.executeSql(SQL_CREATE_TABLE); // 创建数据表
        // 设置数据库的版本,入参为大于0的整数
        store.version = 3;
      }

      // 如果数据库版本不为0且和当前数据库版本不匹配,需要进行升降级操作
      // 当数据库存在并假定版本为1时,例应用从某一版本升级到当前版本,数据库需要从1版本升级到2版本
      if (store.version === 1) {
        // version = 1:表结构:EMPLOYEE (NAME, SALARY, CODES, ADDRESS) => version = 2:表结构:EMPLOYEE (NAME, AGE, SALARY, CODES, ADDRESS)
        if (store !== undefined) {
          (store as relationalStore.RdbStore).executeSql('ALTER TABLE EMPLOYEE ADD COLUMN AGE INTEGER');
          store.version = 2;
        }
      }

      // 当数据库存在并假定版本为2时,例应用从某一版本升级到当前版本,数据库需要从2版本升级到3版本
      if (store.version === 2) {
        // version = 2:表结构:EMPLOYEE (NAME, AGE, SALARY, CODES, ADDRESS) => version = 3:表结构:EMPLOYEE (NAME, AGE, SALARY, CODES)
        if (store !== undefined) {
          (store as relationalStore.RdbStore).executeSql('ALTER TABLE EMPLOYEE DROP COLUMN ADDRESS TEXT');
          store.version = 3;
        }
      }
    });

    // 请确保获取到RdbStore实例后,再进行数据库的增、删、改、查等操作
  }
}

第二步:操作数据库

import { ValuesBucket } from '@ohos.data.ValuesBucket';

let store: relationalStore.RdbStore | undefined = undefined;

let value1 = 'Lisa';
let value2 = 18;
let value3 = 100.5;
let value4 = new Uint8Array([1, 2, 3, 4, 5]);

const valueBucket: ValuesBucket = {
  'NAME': value1,
  'AGE': value2,
  'SALARY': value3,
  'CODES': value4,
};


if (store !== undefined && store as relationalStore.RdbStore) {
  // 调用insert()新增数据
  store.insert('EMPLOYEE', valueBucket, (err: BusinessError, rowId: number) => {})
  
  // 调用update()修改数据
	let predicates = new relationalStore.RdbPredicates('EMPLOYEE'); // 创建表'EMPLOYEE'的predicates
	predicates.equalTo('NAME', 'Lisa'); // 匹配表'EMPLOYEE'中'NAME'为'Lisa'的字段
  store.update(valueBucket, predicates, (err: BusinessError, rows: number) => {})
  
  // 调用delete()删除数据
	predicates = new relationalStore.RdbPredicates('EMPLOYEE');
	predicates.equalTo('NAME', 'Lisa');
  store.delete(predicates, (err: BusinessError, rows: number) => {})
  
  // 调用query()查询数据
  let predicates = new relationalStore.RdbPredicates('EMPLOYEE');
	predicates.equalTo('NAME', 'Rose');
  store.query(predicates, ['ID', 'NAME', 'AGE', 'SALARY'], (err: BusinessError, resultSet) => {
    if (err) {
      console.error(`Failed to query data. Code:${err.code}, message:${err.message}`);
      return;
    }
    
    // resultSet是一个数据集合的游标,默认指向第-1个记录,有效的数据从0开始。
    while (resultSet.goToNextRow()) {
      const id = resultSet.getLong(resultSet.getColumnIndex('ID'));
      const name = resultSet.getString(resultSet.getColumnIndex('NAME'));
      const age = resultSet.getLong(resultSet.getColumnIndex('AGE'));
      const salary = resultSet.getDouble(resultSet.getColumnIndex('SALARY'));
      console.info(`id=${id}, name=${name}, age=${age}, salary=${salary}`);
    }
    // 释放数据集的内存
    resultSet.close();
  })

}
核心API说明:
  • getRdbStore(context, config):获取RdbStore实例,config包含数据库名称、版本以及创建和升级数据库的回调函数。
  • executeSql(sql, params):执行SQL语句,params为SQL语句中的参数。
  • querySql(sql):查询数据库,返回ResultSet对象。
  • ResultSet.getInteger(columnIndex):获取当前行指定列的整数值。
  • ResultSet.getString(columnIndex):获取当前行指定列的字符串值。
使用场景:
  • 用户数据存储:存储应用的用户数据,如用户信息、配置等。
  • 应用数据管理:管理应用内部的各种数据,如缓存数据、日志等。
开发注意事项:
  • 数据库版本升级时,需要在onUpgrade方法中处理数据迁移逻辑。
  • 使用完ResultSet后,记得调用close方法关闭,以释放资源。

1.4 文件(@ohos.file.fs)

获取文件路径

// 获取应用文件路径
let context = getContext(this) as common.UIAbilityContext;
let filesDir = context.filesDir;

创建文件

function createFile(): void {
  // 新建并打开文件
  let file = fs.openSync(filesDir + '/test.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  // 写入一段内容至文件
  let writeLen = fs.writeSync(file.fd, "Try to write str.");
  console.info("The length of str is: " + writeLen);
  // 从文件读取一段内容
  let arrayBuffer = new ArrayBuffer(1024);
  let readOptions: ReadOptions = {
    offset: 0,
    length: arrayBuffer.byteLength
  };
  let readLen = fs.readSync(file.fd, arrayBuffer, readOptions);
  let buf = buffer.from(arrayBuffer, 0, readLen);
  console.info("the content of file: " + buf.toString());
  // 关闭文件
  fs.closeSync(file);
}

读取文件内容并写入到另一个文件

function readWriteFile(): void {
  // 打开文件
  let srcFile = fs.openSync(filesDir + '/test.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  let destFile = fs.openSync(filesDir + '/destFile.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  // 读取源文件内容并写入至目的文件
  let bufSize = 4096;
  let readSize = 0;
  let buf = new ArrayBuffer(bufSize);
  let readOptions: ReadOptions = {
    offset: readSize,
    length: bufSize
  };
  let readLen = fs.readSync(srcFile.fd, buf, readOptions);
  while (readLen > 0) {
    readSize += readLen;
    let writeOptions = {
      length: readLen
    };
    fs.writeSync(destFile.fd, buf, writeOptions);
    readOptions.offset = readSize;
    readLen = fs.readSync(srcFile.fd, buf, readOptions);
  }
  // 关闭文件
  fs.closeSync(srcFile);
  fs.closeSync(destFile);
}

以流的形式读取文件

async function readWriteFileWithStream(): Promise<void> {
  // 打开文件流
  let inputStream = fs.createStreamSync(filesDir + '/test.txt', 'r+');
  let outputStream = fs.createStreamSync(filesDir + '/destFile.txt', "w+");
  // 以流的形式读取源文件内容并写入目的文件
  let bufSize = 4096;
  let readSize = 0;
  let buf = new ArrayBuffer(bufSize);
  let readOptions: ReadOptions = {
    offset: readSize,
    length: bufSize
  };
  let readLen = await inputStream.read(buf, readOptions);
  readSize += readLen;
  while (readLen > 0) {
    await outputStream.write(buf);
    readOptions.offset = readSize;
    readLen = await inputStream.read(buf, readOptions);
    readSize += readLen;
  }
  // 关闭文件流
  inputStream.closeSync();
  outputStream.closeSync();
}

查看文件列表

// 查看文件列表
function getListFile(): void {
  let listFileOption: ListFileOptions = {
    recursion: false,
    listNum: 0,
    filter: {
      suffix: [".png", ".jpg", ".txt"],
      displayName: ["test*"],
      fileSizeOver: 0,
      lastModifiedAfter: new Date(0).getTime()
    }
  };
  let files = fs.listFileSync(filesDir, listFileOption);
  for (let i = 0; i < files.length; i++) {
    console.info(`The name of file: ${files[i]}`);
  }
}
核心API说明:
  • writeFile(path, data, callback):写入数据到指定路径的文件中,callback处理写入结果。
  • readFile(path, callback):读取指定路径的文件,callback处理读取结果。
使用场景:
  • 配置文件:存储和读取应用的配置文件。
  • 缓存数据:缓存应用数据到本地文件。
开发注意事项:
  • 操作文件时要确保文件路径存在且可写。
  • 需要处理文件读写错误的情况。

高级功能-文件压缩与解压

const zipFilePath = '/data/accounts/account_0/appdata/com.example.filetest/files/test.zip';
const filesToZip = ['/data/accounts/account_0/appdata/com.example.filetest/files/test1.txt', '/data/accounts/account_0/appdata/com.example.filetest/files/test2.txt'];

// 压缩文件
fileio.zipFiles(filesToZip, zipFilePath, (err) => {
    if (err) {
        console.error('Failed to zip files: ' + JSON.stringify(err));
        return;
    }
    console.log('Files zipped successfully');
});

// 解压文件
fileio.unzipFile(zipFilePath, '/data/accounts/account_0/appdata/com.example.filetest/unzipped', (err) => {
    if (err) {
        console.error('Failed to unzip file: ' + JSON.stringify(err));
        return;
    }
    console.log('File unzipped successfully');
});
详细API说明:
  • zipFiles(files, zipFilePath, callback):将多个文件压缩到指定路径的ZIP文件中,callback处理压缩结果。
  • unzipFile(zipFilePath, outputDir, callback):解压指定路径的ZIP文件到输出目录,callback处理解压结果。
使用场景:
  • 数据备份:压缩备份数据文件;
  • 数据传输:将多个文件压缩后进行传输,减小传输体积。
开发注意事项:
  • 读写文件时要确保文件路径和输出目录存在且可写;
  • 需要处理压缩和解压过程中可能出现的错误。

二. 网络

2.1 Http请求(@ohos.net.http):

  1. 调用createHttp()方法,创建一个HttpRequest对象。
  2. 调用该对象的on()方法,订阅http响应头事件,此接口会比request请求先返回。可以根据业务需要订阅此消息。
  3. 调用该对象的request()方法,传入http请求的url地址和可选参数,发起网络请求。
  4. 按照实际业务需要,解析返回结果。
  5. 调用该对象的off()方法,取消订阅http响应头事件。
  6. 当该请求使用完毕时,调用destroy()方法主动销毁。
let httpRequest = http.createHttp();
// 用于订阅HTTP响应头,此接口会比request请求先返回。可以根据业务需要订阅此消息
httpRequest.on('headersReceive', (header) => {
  console.info('header: ' + JSON.stringify(header));
});
httpRequest.request(
  "EXAMPLE_URL",
  {
    method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET
    header: {
      'Content-Type': 'application/json'
    },
    // 当使用POST请求时此字段用于传递请求体内容,具体格式与服务端协商确定
    extraData: "data to send",
    expectDataType: http.HttpDataType.STRING, // 可选,指定返回数据的类型
    usingCache: true, // 可选,默认为true
    priority: 1, // 可选,默认为1
    connectTimeout: 60000, // 可选,默认为60000ms
    readTimeout: 60000, // 可选,默认为60000ms
    usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
    usingProxy: false, // 可选,默认不使用网络代理,自API 10开始支持该属性
    caPath:'/path/to/cacert.pem', // 可选,默认使用系统预制证书,自API 10开始支持该属性
    clientCert: { // 可选,默认不使用客户端证书,自API 11开始支持该属性
      certPath: '/path/to/client.pem', // 默认不使用客户端证书,自API 11开始支持该属性
      keyPath: '/path/to/client.key', // 若证书包含Key信息,传入空字符串,自API 11开始支持该属性
      certType: http.CertType.PEM, // 可选,默认使用PEM,自API 11开始支持该属性
      keyPassword: "passwordToKey" // 可选,输入key文件的密码,自API 11开始支持该属性
    },
    multiFormDataList: [ // 可选,仅当Header中,'content-Type'为'multipart/form-data'时生效,自API 11开始支持该属性
      {
        name: "Part1", // 数据名,自API 11开始支持该属性
        contentType: 'text/plain', // 数据类型,自API 11开始支持该属性
        data: 'Example data', // 可选,数据内容,自API 11开始支持该属性
        remoteFileName: 'example.txt' // 可选,自API 11开始支持该属性
      }, {
        name: "Part2", // 数据名,自API 11开始支持该属性
        contentType: 'text/plain', // 数据类型,自API 11开始支持该属性
        // data/app/el2/100/base/com.example.myapplication/haps/entry/files/fileName.txt
        filePath: `${getContext(this).filesDir}/fileName.txt`, // 可选,传入文件路径,自API 11开始支持该属性
        remoteFileName: 'fileName.txt' // 可选,自API 11开始支持该属性
      }
    ]
  }, (err: BusinessError, data: http.HttpResponse) => {
    if (!err) {
      // data.result为HTTP响应内容,可根据业务需要进行解析
      console.info('Result:' + JSON.stringify(data.result));
      console.info('code:' + JSON.stringify(data.responseCode));
      // data.header为HTTP响应头,可根据业务需要进行解析
      console.info('header:' + JSON.stringify(data.header));
      console.info('cookies:' + JSON.stringify(data.cookies)); // 8+
      // 当该请求使用完毕时,调用destroy方法主动销毁
      httpRequest.destroy();
    } else {
      console.error('error:' + JSON.stringify(err));
      // 取消订阅HTTP响应头事件
      httpRequest.off('headersReceive');
      // 当该请求使用完毕时,调用destroy方法主动销毁
      httpRequest.destroy();
    }
  }
);

2.2 WebView(@ohos.web.webview)

import web_webview from '@ohos.web.webview'

controller: web_webview.WebviewController = new web_webview.WebviewController()
//加载在线网页
Web({ src: 'www.example.com', controller: this.controller, renderMode: RenderMode.SYNC_RENDER })

// 通过$rawfile加载本地资源文件。
Web({ src: $rawfile("index.html"), controller: this.controller })

// 通过resource协议加载本地资源文件。
Web({ src: "resource://rawfile/index.html", controller: this.controller })

三. 蓝牙操作

3.1 搜索蓝牙设备

鸿蒙系统支持通过蓝牙API搜索周围的蓝牙设备。以下是一个示例代码:

import bluetooth from '@ohos.bluetooth';

// 启动蓝牙设备搜索
bluetooth.startDiscovery((err, devices) => {
    if (err) {
        console.error('Failed to start discovery: ' + JSON.stringify(err));
        return;
    }
    devices.forEach(device => {
        console.log(`Device found: ${device.name} (${device.address})`);
    });
});

详细API说明:

  • startDiscovery(callback):开始搜索蓝牙设备,callback处理搜索到的设备。
  • device.name:蓝牙设备的名称。
  • device.address:蓝牙设备的地址。

使用场景:

  • 设备配对:搜索并显示周围可用的蓝牙设备以进行配对。
  • 设备信息获取:获取周围蓝牙设备的信息。

开发注意事项:

  • 确保设备的蓝牙功能已打开。
  • 处理搜索过程中的错误,如权限不足等。

3.2 连接蓝牙设备

const deviceAddress = 'XX:XX:XX:XX:XX:XX';

bluetooth.createConnection(deviceAddress, (err, connection) => {
    if (err) {
        console.error('Failed to connect to device: ' + JSON.stringify(err));
        return;
    }
    console.log('Connected to device: ' + deviceAddress);
    
    // 发送数据
    const data = new Uint8Array([0x01, 0x02, 0x03]);
    connection.write(data, (err) => {
        if (err) {
            console.error('Failed to send data: ' + JSON.stringify(err));
        } else {
            console.log('Data sent successfully');
        }
    });
});

详细API说明:

  • createConnection(address, callback):连接到指定地址的蓝牙设备,callback处理连接结果。
  • connection.write(data, callback):向连接的设备发送数据。

使用场景:

  • 数据传输:通过蓝牙向其他设备传输数据。
  • 设备控制:远程控制蓝牙设备。

开发注意事项:

  • 开发时要确保目标设备可连接;
  • 需要处理连接和数据传输过程中的错误。

四. 设备唯一标识符

可以使用ADs kit中的广告ID(OAID)来作为设备唯一标识符

import identifier from '@ohos.identifier.oaid';

try {
  identifier.getOAID().then((data) => {
    const oaid: string = data;
  }).catch((err: BusinessError) => {
    ...
  })
} catch (err) {
	...
}
  
try {
  identifier.getOAID((err: BusinessError, data: string) => {
    if (err.code) {
      ...
    } else {
      const oaid: string = data;
    }
   });
} catch (err) {
  ...
}

五. 日志打印

5.1 Hilog日志

HiLog中定义了DEBUG、INFO、WARN、ERROR、FATAL五种日志级别,并提供了对应的方法输出不同级别的日志

接口名功能描述
isLoggable(domain: number, tag: string, level: LogLevel)在打印日志前调用该接口,检查指定领域标识、日志标识和级别的日志是否可以打印。
debug(domain: number, tag: string, format: string, ...args: any[])输出DEBUG级别日志。仅用于应用/服务调试。在DevEco Studio的terminal窗口或cmd里,通过命令“hdc shell hilogcat”设置可打印日志的等级为DEBUG。
info(domain: number, tag: string, format: string, ...args: any[])输出INFO级别日志。表示普通的信息。
warn(domain: number, tag: string, format: string, ...args: any[])输出WARN级别日志。表示存在警告。
error(domain: number, tag: string, format: string, ...args: any[])输出ERROR级别日志。表示存在错误。
fatal(domain: number, tag: string, format: string, ...args: any[])输出FATAL级别日志。表示出现致命错误、不可恢复错误。

5.2 Console日志

const number = 5;

console.debug('count: %d', number);  // 格式化输出替换message中的文本。
// count: 5 
console.debug('count:', number);  // 打印message以及其余信息
// count: 5 
console.debug('count:'); // 仅打印message
// count: 

console.log('count: %d', number);  
console.info('count: %d', number);
console.warn('warn: %d', str);
console.error('error: %d', str);

六. 命令行工具

HDC常用命令及和Android ADB命令的对比(以下表格来源于网络)

HDCADB说明
hdc -hadb --help查看帮助
hdc -vadb --version查看版本
hdc list targetsadb devices查看连接设备
hdc killadb kill-server结束服务
hdc kill -radb start-server启动服务
hdc app install 安装包路径adb install 安装包路径安装应用
hdc app uninstall packageadb uninstall package卸载应用
hdc hilogadb logcat抓取log
hdc shell hilogcat >log.logadb shell logcat >log.log抓取log并保存
hdc shell rebootadb reboot重启设备
hdc shell bm get -uadb shell bm get -u获取UUID
hdc file recv REMOTE… LOCALadb pull REMOTE… LOCAL接收文件 REMOTE:手机 LOCAL:PC
hdc file send LOCAL… REMOTEadb push LOCAL… REMOTE发送文件
hdc shell screencap filenameadb shell screencap filename截屏
hdc shell screenrecord filenameadb shell screenrecord filename录屏