Dispose 在 Flutter、Android、iOS、Web、鸿蒙 多端的应用详解

内容分享2天前发布
0 0 0

本文档全面介绍 Dispose / 资源释放机制 在五大平台的应用方式、常见场景、注意事项与最佳实践,包括:

FlutterAndroidiOSWeb鸿蒙(HarmonyOS)

Dispose 的核心意义:

释放非内存资源,终止后台行为,防止资源泄漏。


1. Flutter 中的 Dispose

Flutter 使用 Dart 的垃圾回收(GC)自动管理内存,但以下资源必须手动释放:

AnimationControllerTextEditingController / ScrollController / PageControllerStreamSubscriptionStreamControllerTimerFocusNodeChangeNotifier

1.1 AnimationController


class DemoState extends State<Demo> with SingleTickerProviderStateMixin {
  late AnimationController controller;

  @override
  void initState() {
    super.initState();
    controller = AnimationController(vsync: this);
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }
}

1.2 TextEditingController / ScrollController


final textController = TextEditingController();
final scrollController = ScrollController();

override
void dispose() {
  textController.dispose();
  scrollController.dispose();
  super.dispose();
}

1.3 StreamSubscription


late StreamSubscription sub;

@override
void initState() {
  super.initState();
  sub = stream.listen((event) {});
}

@override
void dispose() {
  sub.cancel();
  super.dispose();
}

1.4 Timer


Timer? timer;

override
void initState() {
  super.initState();
  timer = Timer.periodic(Duration(seconds: 1), (_) {});
}

override
void dispose() {
  timer?.cancel();
  super.dispose();
}

1.5 StreamController


final controller = StreamController<int>();

@override
void dispose() {
  controller.close();
  super.dispose();
}

2. Android 中的 Dispose / 资源释放

Android 的资源释放方式包括:


dispose()
(如 RxJava)
cancel()
(如 Coroutine Job)
release()
(如 Camera、MediaPlayer)
close()
(如 IO、Cursor)
unbind()
(如 Service)

2.1 RxJava dispose()


private var disposable: Disposable? = null

override fun onDestroy() {
    disposable?.dispose()
    super.onDestroy()
}

2.2 Coroutine Job.cancel()


private val job = Job()

override fun onCleared() {
    job.cancel()
    super.onCleared()
}

2.3 Camera / MediaPlayer


mediaPlayer.release()
cameraProvider.unbindAll()

2.4 BroadcastReceiver


unregisterReceiver(receiver)

2.5 WebSocket


webSocket.close(1000, "done")

3. iOS 中的 Dispose / 清理机制

iOS 依赖 ARC 自动管理内存,但许多资源仍需手动清理:

Combine AnyCancellable(cancel)Timer(invalidate)NotificationCenter 观察者(removeObserver)KVO(removeObserver)Socket / 文件句柄GCD WorkItem

3.1 Combine cancel()


var cancellable: AnyCancellable?

cancellable = publisher.sink { value in
    print(value)
}

cancellable?.cancel()   // 等价 dispose

3.2 Timer


timer.invalidate()
timer = nil

3.3 NotificationCenter


NotificationCenter.default.removeObserver(self)

3.4 KVO


object.removeObserver(self, forKeyPath: "name")

3.5 Socket


close(socketFd)

4. Web 中的 Dispose / 清理资源

Web 没有统一的 dispose 概念,但所有可能“持续占用资源”的对象需手动清理:

EventListenersetInterval / setTimeoutWebSocketFetch AbortControllerWeb Worker地图对象(如 Mapbox / Leaflet)React useEffect 清理函数

4.1 EventListener


element.addEventListener('click', handler);
// dispose
element.removeEventListener('click', handler);

4.2 setInterval / setTimeout


clearInterval(id);
clearTimeout(id);

4.3 WebSocket


socket.close();

4.4 AbortController


controller.abort();

4.5 React useEffect


useEffect(() => {
  const id = setInterval(() => {}, 1000);
  return () => clearInterval(id); // dispose
}, []);

4.6 Worker


worker.terminate();

5. 鸿蒙(HarmonyOS)中的 Dispose

鸿蒙使用 ArkTS,资源释放具有以下特征:

需要释放定时器需要关闭 WebSocket需要释放 MediaPlayer / Camera需要销毁订阅(off)需要在 Page 生命周期中清理

5.1 数据订阅


let subscriber = data.on('update', () => {});
subscriber.off('update');

5.2 Timer


clearTimeout(timer);
clearInterval(timer);

5.3 WebSocket


websocket.close();

5.4 MediaPlayer


mediaPlayer.release();

5.5 Page 生命周期


onPageDestroy() {
  timer && clearInterval(timer);
  controller.dispose();
}

6. 五端对比总结

平台 释放方式 常见资源 生命周期点
Flutter dispose(), cancel(), close() Controller、Stream、Timer、Animation dispose()
Android dispose()、release()、cancel()、close() Rx、协程、媒体、广播、IO onDestroy/onCleared
iOS cancel()、invalidate()、removeObserver() Timer、KVO、通知、Combine deinit/viewDidDisappear
Web removeEventListener()、clearInterval()、close() DOM、计时器、WS、worker unmount/beforeunload
鸿蒙 off()、release()、close() Timer、订阅、媒体、WS onPageDestroy

7. 最佳实践

所有跨生命周期持续运行的对象必须释放避免在单例中持有 UI 上下文避免未关闭数据流、socket、timer优先使用平台提供的自动化方案(Lifecycle、Combine、React hooks)

© 版权声明

相关文章

暂无评论

none
暂无评论...