You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter在Android13设备执行PDF压缩长任务时应用闪退

解决Android 13(Realme/Samsung设备)Flutter应用PDF压缩时崩溃的问题

问题现象

在Realme/Samsung品牌的Android 13物理设备上,Flutter应用调用PdfCompression库执行PDF压缩这类长耗时任务时,应用会自动关闭,同时日志输出:

F/crash_dump64(14834): crash_dump.cpp:494] failed to attach to thread 609: Permission denied

问题分析

这个错误的核心是系统限制了崩溃日志工具crash_dump64附加到应用线程的权限,而触发根源是长耗时的PDF压缩任务阻塞主线程导致ANR(应用无响应),加上Android 13对后台进程、线程权限的收紧,以及Realme/Samsung定制ROM额外的后台进程管控机制,最终导致应用被系统强制终止。

解决方案

1. 将压缩任务移至Isolate(后台线程)

Flutter主线程负责UI渲染,不能处理长耗时任务,必须通过Isolate隔离执行压缩操作,避免阻塞主线程触发ANR:

import 'dart:isolate';
import 'package:pdf_compression/pdf_compression.dart';

// 启动Isolate执行压缩
Future<void> runPdfCompressionInIsolate(String inputPath, String outputPath) async {
  final receivePort = ReceivePort();
  await Isolate.spawn(_compressPdf, [receivePort.sendPort, inputPath, outputPath]);
  
  final result = await receivePort.first;
  if (result is String) {
    // 处理压缩成功逻辑
  } else if (result is Exception) {
    // 处理压缩异常
  }
}

// Isolate内部执行压缩的方法
void _compressPdf(List<dynamic> args) {
  final sendPort = args[0] as SendPort;
  final inputPath = args[1] as String;
  final outputPath = args[2] as String;
  
  try {
    final compressionResult = PdfCompression.compressPdf(inputPath, outputPath);
    sendPort.send(compressionResult);
  } catch (e) {
    sendPort.send(Exception('压缩失败: ${e.toString()}'));
  }
}

2. 申请必要的Android权限

Android 13对后台运行权限管控严格,需在AndroidManifest.xml中添加权限声明:

<!-- 前台服务权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- 通知权限(前台服务必须) -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- 忽略电池优化,避免任务被系统强制中断 -->
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

同时在Flutter代码中动态申请权限:

import 'package:permission_handler/permission_handler.dart';

Future<void> requestRequiredPermissions() async {
  // 请求通知权限
  final notificationPerm = await Permission.notification.request();
  if (!notificationPerm.isGranted) {
    // 引导用户前往设置开启权限
  }
  
  // 请求忽略电池优化权限
  final batteryPerm = await Permission.ignoreBatteryOptimizations.request();
  if (!batteryPerm.isGranted) {
    await openAppSettings();
  }
}

3. 用前台服务执行长耗时任务

对于超过10分钟的压缩任务,Android 13要求必须使用前台服务,避免被系统后台杀进程。可以借助flutter_foreground_task库实现:

import 'package:flutter_foreground_task/flutter_foreground_task.dart';

// 前台服务回调入口
@pragma('vm:entry-point')
void foregroundTaskCallback() {
  FlutterForegroundTask.setTaskHandler(PdfCompressionTaskHandler());
}

// 自定义前台任务处理器
class PdfCompressionTaskHandler extends TaskHandler {
  @override
  Future<void> onStart(DateTime timestamp, SendPort? sendPort) async {
    // 在这里执行Isolate压缩任务
    await runPdfCompressionInIsolate('input.pdf', 'output_compressed.pdf');
    // 任务完成后停止前台服务
    await FlutterForegroundTask.stopService();
  }

  @override
  Future<void> onEvent(DateTime timestamp, SendPort? sendPort) async {}

  @override
  Future<void> onDestroy(DateTime timestamp, SendPort? sendPort) async {}
}

// 启动前台服务并执行压缩
Future<void> startCompressionWithForegroundService() async {
  await FlutterForegroundTask.startService(
    notificationTitle: 'PDF压缩中',
    notificationText: '任务进行中,请保持应用在前台',
    callback: foregroundTaskCallback,
  );
}

4. 检查库的兼容性

确认使用的PdfCompression库已适配Android 13,若为旧版本,尝试升级到最新版;若问题仍存在,可考虑替换为更稳定的PDF处理库(如基于Apache PDFBox的Flutter封装)。

内容的提问来源于stack exchange,提问作者aarmaan hussain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 11:53:10