关于在部分Android设备上压后台一段时候后再返回软件卡死的处理

59 阅读1分钟

我在使用Flutter编写Android程序的时候发现,在个别设备上压后台,然后等待1分半钟左右再回来会出现卡死的情况。

我当时是使用 OverlayEntry

代码如下:

import 'dart:async';
import 'package:flutter/material.dart';

class CustomOverlayEntry extends StatefulWidget {
  final VoidCallback closeOverlayEntry;
  final VoidCallback? updateIconState;
  final Widget child;

  final double? top;
  final double? bottom;
  final double? left;
  final double? right;

  final double width;
  final double height;

  const CustomOverlayEntry({
    super.key,
    required this.closeOverlayEntry,
    required this.child,
    required this.width,
    required this.height,
    this.top,
    this.bottom,
    this.left,
    this.right,
    this.updateIconState,
  });

  @override
  State<CustomOverlayEntry> createState() => _CustomOverlayEntryState();
}

class _CustomOverlayEntryState extends State<CustomOverlayEntry> with WidgetsBindingObserver {
  bool isShow = false;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }



  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) async {
    print('didChangeAppLifecycleState state : $state');
    if (state == AppLifecycleState.paused) {
      setState(() {
        isShow = false;
      });

      await Future.delayed(const Duration(milliseconds: 200));

      if (mounted) {
        widget.closeOverlayEntry();
        widget.updateIconState?.call();
      }
    }
  }

  Future<void> _handleBackgroundTap() async {
    if (!mounted || !isAppResumed || !isShow) return;

    setState(() {
      isShow = false;
    });

    await Future.delayed(const Duration(milliseconds: 200));

    if (mounted) {
      widget.closeOverlayEntry();
      widget.updateIconState?.call();
    }
  }

  @override
  Widget build(BuildContext context) {
    return MediaQuery.removePadding(
      context: context,
      removeTop: true,
      removeBottom: true,
      child: Scaffold(
        backgroundColor: Colors.transparent,
        body: Stack(
          children: [
            Positioned.fill(
              child: GestureDetector(
                behavior: HitTestBehavior.translucent,
                onTap: _handleBackgroundTap,
                child: Container(color: Colors.transparent),
              ),
            ),

              Positioned(
                top: widget.top,
                bottom: widget.bottom,
                left: widget.left,
                right: widget.right,
                child: AnimatedOpacity(
                  opacity: isShow ? 1.0 : 0.0,
                  duration: const Duration(milliseconds: 100),
                  child: Container(
                    width: widget.width,
                    height: widget.height,
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(5),
                    ),
                    padding: const EdgeInsets.symmetric(vertical: 10),
                    child: widget.child,
                  ),
                ),
              
          ],
        ),
      ),
    );
  }
}

我选择的方式是在压后台之后直接关闭悬浮窗。