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

Flutter安卓应用设置壁纸后崩溃(仅红米设备出现)

Flutter安卓应用红米设备设置壁纸后卡顿崩溃(仅MIUI平台复现)

问题背景

应用设置壁纸后立即卡顿并崩溃,壁纸配置为每分钟自动更换。该问题仅在红米设备(MIUI系统)上出现,诺基亚设备无异常。

核心代码逻辑

通过AndroidAlarmManager.periodic周期性调用myfunction实现自动换壁纸:

static Future<void> myfunction()async{
  final response = await http.get(Uri.parse("my url here"));
  var jsonData = json.decode(response.body);
  results = jsonData;
  var url = results["urls"]["full"];
  String result;
  var progressString = Wallpaper.imageDownloadProgress(url);

  progressString.listen((data) {
    print("DataReceived: " + data);
  }, onDone: () async {
    if (Globals.selectedScreen.toString() == 'home') {
      try {
        await Wallpaper.homeScreen();
      } catch (e) {
        debugPrint(e);
      }
    } else if (Globals.selectedScreen.toString() == 'lock') {
      try {
        await Wallpaper.lockScreen();
      } catch (e) {
        debugPrint(e);
      }
    } else {
      try {
        await Wallpaper.bothScreen();
      } catch (e) {
        debugPrint(e);
      }
    }
  });
}

崩溃日志(中文翻译)

DataReceived: 100%
W/MIUIScout App(13194): 进入APP_SCOUT_WARNING状态
W/MIUIScout App(13194): 事件:APP_SCOUT_WARNING 线程:main 调用栈:
W/MIUIScout App(13194): at android.graphics.Bitmap.nativeCompress(Native Method)
W/MIUIScout App(13194): at android.graphics.Bitmap.compress(Bitmap.java:1445)
W/MIUIScout App(13194): at android.app.WallpaperManager.setBitmap(WallpaperManager.java:1535)
W/MIUIScout App(13194): at android.app.WallpaperManager.setBitmap(WallpaperManager.java:1506)
W/MIUIScout App(13194): at com.prateektimer.wallpaper.WallpaperPlugin.setHomeLockScreen(WallpaperPlugin.java:182)
W/MIUIScout App(13194): at com.prateektimer.wallpaper.WallpaperPlugin.onMethodCall(WallpaperPlugin.java:91)
W/MIUIScout App(13194): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262)
W/MIUIScout App(13194): at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295)
W/MIUIScout App(13194): at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$DartMessenger(DartMessenger.java:319)
W/MIUIScout App(13194): at io.flutter.embedding.engine.dart.-$$Lambda$DartMessenger$TsixYUB5E6FpKhMtCSQVHKE89gQ.run(Unknown Source:12)
W/MIUIScout App(13194): at android.os.Handler.handleCallback(Handler.java:938)
W/MIUIScout App(13194): at android.os.Handler.dispatchMessage(Handler.java:99)
W/MIUIScout App(13194): at android.os.Looper.loopOnce(Looper.java:210)
W/MIUIScout App(13194): at android.os.Looper.loop(Looper.java:299)
W/MIUIScout App(13194): at android.app.ActivityThread.main(ActivityThread.java:8168)
W/MIUIScout App(13194): at java.lang.reflect.Method.invoke(Native Method)
W/MIUIScout App(13194): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556)
W/MIUIScout App(13194): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1037)
I/libc (13194): 请求为线程13194 (ample.app)生成崩溃转储

问题分析

从日志可以定位,崩溃发生在Bitmap.nativeCompress方法,即系统压缩Bitmap为壁纸格式的环节。MIUI的APP_SCOUT机制触发警告,说明主线程被耗时操作阻塞,超过了MIUI的监控阈值,核心原因包括:

  • 下载的原图分辨率过高,压缩时占用大量主线程资源
  • 壁纸设置操作直接在主线程执行,MIUI对主线程耗时管控比其他安卓系统更严格
  • 使用的Wallpaper插件未针对MIUI做后台线程优化,导致主线程阻塞

解决方案

1. 将壁纸设置移到后台线程

用Flutter的compute函数将耗时操作转移到后台线程,避免阻塞主线程:

// 封装壁纸设置逻辑
Future<void> _setWallpaper() async {
  switch(Globals.selectedScreen.toString()) {
    case 'home':
      try { await Wallpaper.homeScreen(); } catch(e) { debugPrint(e.toString()); }
      break;
    case 'lock':
      try { await Wallpaper.lockScreen(); } catch(e) { debugPrint(e.toString()); }
      break;
    default:
      try { await Wallpaper.bothScreen(); } catch(e) { debugPrint(e.toString()); }
  }
}

// 修改onDone回调
progressString.listen((data) {
  print("DataReceived: " + data);
}, onDone: () async {
  await compute(_setWallpaper, null);
});

2. 压缩图片后再设置

先将下载的图片压缩到适配设备屏幕的尺寸,减少Bitmap内存占用:
可使用flutter_image_compress插件实现:

import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';

// 下载并压缩图片
Future<String> _downloadAndCompressImage(String url) async {
  final response = await http.get(Uri.parse(url));
  final tempDir = await getTemporaryDirectory();
  final tempFile = File('${tempDir.path}/temp_wp.jpg');
  await tempFile.writeAsBytes(response.bodyBytes);

  // 压缩到设备屏幕尺寸(需替换为实际设备分辨率)
  final compressedFile = await FlutterImageCompress.compressAndGetFile(
    tempFile.path,
    '${tempDir.path}/compressed_wp.jpg',
    quality: 80,
    width: 1080,
    height: 2340,
  );

  return compressedFile!.path;
}

// 修改myfunction逻辑
static Future<void> myfunction()async{
  final response = await http.get(Uri.parse("my url here"));
  var jsonData = json.decode(response.body);
  var url = jsonData["urls"]["full"];
  
  // 先压缩图片
  final compressedPath = await _downloadAndCompressImage(url);
  // 若插件支持本地路径,直接传入设置;否则需将文件转为Bitmap后处理
}

3. 优化周期性任务

  • 添加任务锁,避免前一次壁纸设置未完成时启动新任务,防止资源冲突
  • 增加错误重试机制,避免单次失败直接崩溃
  • 锁屏时暂停任务,减少不必要的资源消耗

4. MIUI适配调整

  • 确认应用已申请必要权限(如安卓10以下的WRITE_EXTERNAL_STORAGE)
  • 临时关闭开发者选项中的APP Scout监控(仅用于测试,不建议作为最终方案)

内容的提问来源于stack exchange,提问作者abhijith k sabu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:45:48