普通视图

发现新文章,点击刷新页面。
今天 — 2025年8月28日首页

第8章 事件、权限与安全

作者 小喷友
2025年8月28日 09:32

8.1 事件系统与消息机制

在 HarmonyOS 中,事件和消息机制主要用于 组件之间、应用内部以及应用与系统之间的通信

常见的事件机制:

  1. UI事件

    • 点击、长按、滑动等。
    Button("点击我")
      .onClick(() => {
        console.log("按钮被点击");
      })
    
  2. 应用内事件(EventHub)

    • 可以在不同模块间传递消息。
    import EventHub from '@ohos.eventhub';
    
    // 发布事件
    EventHub.emit("userLogin", { userId: 101 });
    
    // 订阅事件
    EventHub.on("userLogin", (data) => {
      console.log(`用户 ${data.userId} 登录成功`);
    });
    
  3. 系统事件

    • 如电量变化、网络状态变化。
    import battery from '@ohos.battery';
    
    battery.on("batteryInfoChange", (info) => {
      console.log("当前电量: " + info.level);
    });
    

8.2 常用权限管理

HarmonyOS 为了保护用户隐私,很多功能都需要 动态申请权限

📌 常见权限:

  • ohos.permission.INTERNET(网络)
  • ohos.permission.CAMERA(相机)
  • ohos.permission.READ_CONTACTS(读取联系人)
  • ohos.permission.LOCATION(位置信息)

module.json5 中声明权限:

{
  "module": {
    "reqPermissions": [
      { "name": "ohos.permission.CAMERA" },
      { "name": "ohos.permission.LOCATION" }
    ]
  }
}

动态申请权限

import abilityAccessCtrl from '@ohos.abilityAccessCtrl';

async function requestCameraPermission() {
  let atManager = abilityAccessCtrl.createAtManager();
  let result = await atManager.requestPermissionsFromUser(
    this.context,
    ["ohos.permission.CAMERA"]
  );

  if (result.authResults[0] === 0) {
    console.log("用户允许相机权限");
  } else {
    console.log("用户拒绝相机权限");
  }
}

8.3 数据安全与隐私保护

  1. 本地数据加密

    • 存储用户数据前,应使用加密(如 AES)。
    import cryptoFramework from '@ohos.security.cryptoFramework';
    
    async function encryptData(text: string) {
      const cipher = cryptoFramework.createCipher("AES128|ECB|PKCS7");
      cipher.init(cryptoFramework.Cipher.ENCRYPT_MODE, "mySecretKey");
      return cipher.doFinal(text);
    }
    
  2. 敏感信息存储

    • 推荐使用 Preferences + 加密。
    import dataPreferences from '@ohos.data.preferences';
    
    async function saveToken(context, token: string) {
      let pref = await dataPreferences.getPreferences(context, "user_prefs");
      await pref.put("access_token", token);
      await pref.flush();
    }
    
  3. 隐私合规

    • 在应用首次启动时弹出 隐私协议与权限说明
    • 不允许未授权前就采集敏感数据。

8.4 异常处理与日志

  1. 异常捕获

    • 避免因未处理的异常导致应用崩溃。
    try {
      let result = riskyOperation();
    } catch (err) {
      console.error("发生异常: " + err.message);
    }
    
  2. 日志记录

    • HarmonyOS 提供 hilog 模块。
    import hilog from '@ohos.hilog';
    
    hilog.info(0x0000, 'APP', '应用启动');
    hilog.error(0x0001, 'APP', '发生错误: %{public}s', "网络异常");
    

    注意:%{public} 表示日志内容可见,%{private} 表示敏感内容不会显示。

  3. 全局异常捕获

    import { AppStorage } from '@ohos.stage';
    
    AppStorage.setOrCreate("errorHandler", (err) => {
      hilog.error(0x0001, "APP", "全局异常: " + err.message);
    });
    

8.5 实操:权限申请与异常日志记录

目标

  1. 打开应用时请求相机权限。
  2. 点击按钮时尝试打开相机,若失败则记录异常日志。

示例代码

import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
import hilog from '@ohos.hilog';

@Entry
@Component
struct MainPage {
  @State message: string = "请先申请权限";

  build() {
    Column({ space: 20 }) {
      Text(this.message).fontSize(22)

      Button("申请相机权限").onClick(() => {
        this.requestPermission();
      })

      Button("打开相机").onClick(() => {
        this.openCamera();
      })
    }
    .padding(20)
  }

  async requestPermission() {
    try {
      let atManager = abilityAccessCtrl.createAtManager();
      let result = await atManager.requestPermissionsFromUser(
        this.context,
        ["ohos.permission.CAMERA"]
      );
      if (result.authResults[0] === 0) {
        this.message = "相机权限已授予";
      } else {
        this.message = "用户拒绝相机权限";
      }
    } catch (err) {
      hilog.error(0x0001, "APP", "权限申请异常: %{public}s", err.message);
    }
  }

  openCamera() {
    try {
      // 假设这里调用相机
      throw new Error("相机初始化失败");
    } catch (err) {
      hilog.error(0x0001, "APP", "相机异常: %{public}s", err.message);
      this.message = "相机打开失败,请查看日志";
    }
  }
}

8.6 小结

本章学习了:

  • 事件与消息机制(UI 事件、应用内事件、系统事件)
  • 权限管理(声明权限 + 动态申请)
  • 数据安全与隐私保护(加密存储、隐私合规)
  • 异常处理与日志(try-catch、hilog、全局异常)
  • 实操:相机权限申请 + 日志记录
昨天 — 2025年8月27日首页

阶段一:入门(理解 Rust 的基本概念)

作者 小喷友
2025年8月27日 10:23

1. 安装与工具链

  1. 安装 Rust:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup update
  1. 工具介绍:
  • rustc main.rs 编译单个 Rust 文件
  • cargo new project_name 创建项目
  • cargo build 构建项目
  • cargo run 构建并运行
  • cargo check 仅检查语法,不编译
  1. 配置 IDE:
  • VS Code + rust-analyzer 插件
  • IntelliJ + Rust 插件

2. Rust 基础语法

变量与可变性

fn main() {
    let x = 5;      // 不可变变量
    let mut y = 10; // 可变变量
    y += 5;
    println!("x = {}, y = {}", x, y);
}

基本数据类型

let a: i32 = 10;        // 整数
let b: f64 = 3.14;      // 浮点数
let c: bool = true;     // 布尔
let d: char = 'R';      // 字符

字符串类型

let s1: &str = "hello";       // 字符串切片
let s2: String = String::from("world"); // 可变字符串

常量与静态变量

const PI: f64 = 3.14159;
static mut COUNTER: i32 = 0;

3. 控制流

if / else

let n = 10;
if n % 2 == 0 {
    println!("偶数");
} else {
    println!("奇数");
}

loop / while / for

let mut i = 0;
while i < 5 {
    println!("{}", i);
    i += 1;
}

for j in 0..5 {
    println!("{}", j);
}

loop {
    println!("无限循环");
    break;
}

match 模式匹配

let number = 3;
match number {
    1 => println!("一"),
    2 => println!("二"),
    3 => println!("三"),
    _ => println!("其他"),
}

4. 函数和作用域

fn add(a: i32, b: i32) -> i32 {
    a + b
}

fn main() {
    let result = add(5, 10);
    println!("5 + 10 = {}", result);
}
  • 变量作用域:在函数或块外部不可访问内部变量
  • 生命周期初探:变量在离开作用域时被释放

5. 简单练习

  1. 计算 Fibonacci 数列
fn fibonacci(n: u32) -> u32 {
    if n == 0 { 0 } 
    else if n == 1 { 1 } 
    else { fibonacci(n-1) + fibonacci(n-2) }
}

fn main() {
    for i in 0..10 {
        println!("Fibonacci({}) = {}", i, fibonacci(i));
    }
}
  1. 判断素数
fn is_prime(n: u32) -> bool {
    if n <= 1 { return false; }
    for i in 2..n {
        if n % i == 0 {
            return false;
        }
    }
    true
}

fn main() {
    let num = 17;
    println!("{} 是素数吗? {}", num, is_prime(num));
}
  1. 简单猜数字游戏
use std::io;
use rand::Rng;

fn main() {
    let secret = rand::thread_rng().gen_range(1..=100);
    println!("猜一个 1 到 100 的数字:");

    loop {
        let mut guess = String::new();
        io::stdin().read_line(&mut guess).expect("读取失败");
        let guess: u32 = guess.trim().parse().expect("请输入数字");

        if guess < secret {
            println!("太小了!");
        } else if guess > secret {
            println!("太大了!");
        } else {
            println!("猜对了!");
            break;
        }
    }
}
昨天以前首页
❌
❌