☰分类导航

软件工程/高级特性与性能优化
课程进度 56% · 第7/11章第7/11章 · 标签 1/6
— 1 —

多线程与异步

原线程与Handler示例依赖Activity、View和业务函数;异步任务还需取消与结果归属。性能建议不是通用开关:弱引用不能代替清理,setHasFixedSize也不能修复错误尺寸假设。

Android 主线程(UI 线程)负责界面更新,耗时操作必须在子线程执行,否则会导致 ANR(应用无响应)。

耗时任务迁出主线程只是第一步,还要控制并发、取消和结果归属。页面离开时任务未必停止,较旧请求也可能比新请求晚返回。先定义当前请求身份与拥有者,再判断回调能否更新界面,不能只依赖一次runOnUiThread保证所有异步正确性。


```java
// 子线程执行任务
new Thread(() -> {
    // 耗时操作
    final String result = doHeavyWork();
    // 切换到主线程更新 UI
    runOnUiThread(() -> textView.setText(result));
}).start();

// Handler 用法
Handler handler = new Handler(Looper.getMainLooper());
handler.post(() -> {
    // 主线程更新 UI
    textView.setText("更新完成");
});

// 延迟执行
handler.postDelayed(() -> {
    // 延迟 1 秒执行
}, 1000);
```
java
1
// 子线程执行任务
2
new Thread(() -> {
3
// 耗时操作
4
final String result = doHeavyWork();
5
// 切换到主线程更新 UI
6
runOnUiThread(() -> textView.setText(result));
7
}).start();
8
 
9
// Handler 用法
10
Handler handler = new Handler(Looper.getMainLooper());
11
handler.post(() -> {
12
// 主线程更新 UI
13
textView.setText("更新完成");
14
});
15
 
16
// 延迟执行
17
handler.postDelayed(() -> {
18
// 延迟 1 秒执行
19
}, 1000);

📖Android 不允许在子线程直接更新 UI,必须通过 runOnUiThread 或 Handler 切换到主线程

— 2 —

性能优化技巧

  • 避免内存泄漏 —— 使用弱引用(WeakReference)、及时释放资源、注意静态变量引用
  • 布局优化 —— 减少布局嵌套深度,使用 ConstraintLayout 替代多层 LinearLayout
  • 图片压缩与缓存 —— 使用 Glide 等图片库自动处理,避免大图直接加载到内存
  • ViewStub 延迟加载 —— 不常用的布局使用 ViewStub 按需加载
  • SparseArray —— 替代 HashMap<Integer, Object>,内存更高效
  • 避免在 onDraw 中创建对象 —— 在构造函数中预先创建 Paint、Path 等对象
  • 使用 RecyclerView 的 setHasFixedSize(true) 提高列表性能
◆

常用性能分析工具

  • Android Profiler —— CPU、内存、网络实时监控
  • Memory Profiler —— 检测内存泄漏与内存抖动
  • CPU Profiler —— 分析方法耗时与线程状态
  • LeakCanary —— 自动检测内存泄漏
  • StrictMode —— 检测主线程上的 IO 与网络操作