Flutter(仅Android)自定义应用无法显示问题求助
排查device_apps库无法展示指定包名应用的问题
问题
使用device_apps库展示指定包名的自定义应用,点击Custom Apps按钮后无任何内容显示。
代码错误分析
myApps初始化错误
原代码中late Future<List<Application>>? myApps = [] as Future<List<Application>>?;是错误的强制类型转换,把空列表直接转为Future对象,导致后续无法正确向列表添加应用。loadMyApps方法逻辑错误
通过then和whenComplete嵌套操作myApps的Future结果,这种方式不仅逻辑混乱,还无法正确收集应用数据。应该创建普通列表,逐个获取应用并添加。FutureBuilder重复调用
loadMyApps
每次build都会调用loadMyApps(),导致重复发起请求,同时没有正确利用Future的生命周期。FutureBuilder状态判断不准确
原代码只判断data.data == null,忽略了Future的连接状态,会导致初始状态一直显示加载指示器,而数据返回后也无法正确渲染。
修复后的代码
import 'package:device_apps/device_apps.dart'; import 'package:flutter/material.dart'; class CustomApps extends StatefulWidget { const CustomApps({super.key}); @override State<CustomApps> createState() => _CustomAppsState(); } class _CustomAppsState extends State<CustomApps> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Custom Apps"), ), body: const _CustomAppsList(), ); } } class _CustomAppsList extends StatefulWidget { const _CustomAppsList({Key? key}) : super(key: key); @override State<_CustomAppsList> createState() => _CustomAppsListState(); } class _CustomAppsListState extends State<_CustomAppsList> { late Future<List<Application>> _myAppsFuture; Future<List<Application>> loadMyApps() async { final List<Application> apps = []; // 逐个获取应用并添加到列表 final oneConnect = await DeviceApps.getApp('com.samsung.android.oneconnect'); if (oneConnect != null) apps.add(oneConnect); final easyMover = await DeviceApps.getApp('com.sec.android.easyMover'); if (easyMover != null) apps.add(easyMover); final timeZoneUpdate = await DeviceApps.getApp('com.samsung.android.timezone.autoupdate_O'); if (timeZoneUpdate != null) apps.add(timeZoneUpdate); return apps; } @override void initState() { super.initState(); // 在initState中初始化Future,避免重复调用 _myAppsFuture = loadMyApps(); } @override Widget build(BuildContext context) { return FutureBuilder<List<Application>>( future: _myAppsFuture, builder: (BuildContext context, AsyncSnapshot<List<Application>> snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } else if (snapshot.hasError) { return Center(child: Text('加载出错: ${snapshot.error}')); } else if (!snapshot.hasData || snapshot.data!.isEmpty) { return const Center(child: Text('没有找到指定应用')); } else { List<Application> apps = snapshot.data!; return Scrollbar( child: ListView.builder( itemBuilder: (BuildContext context, int position) { Application app = apps[position]; return Column( children: <Widget>[ ListTile( leading: app is ApplicationWithIcon ? CircleAvatar( backgroundImage: MemoryImage(app.icon), backgroundColor: Colors.white, ) : null, onTap: () => onAppClicked(context, app), title: Text('${app.appName} (${app.packageName})'), subtitle: Text('Version: ${app.versionName}\n' 'System app: ${app.systemApp}\n' 'APK file path: ${app.apkFilePath}\n' 'Data dir: ${app.dataDir}\n' 'Installed: ${DateTime.fromMillisecondsSinceEpoch(app.installTimeMillis).toString()}\n' 'Updated: ${DateTime.fromMillisecondsSinceEpoch(app.updateTimeMillis).toString()}'), ), const Divider( height: 1.0, ) ], ); }, itemCount: apps.length), ); } }); } } void onAppClicked(BuildContext context, Application app) { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text(app.appName), actions: <Widget>[ _AppButtonAction( label: '打开应用', onPressed: () => app.openApp(), ), _AppButtonAction( label: '打开应用设置', onPressed: () => app.openSettingsScreen(), ), _AppButtonAction( label: '卸载应用', onPressed: () async => app.uninstallApp(), ), ], ); }); } class _AppButtonAction extends StatelessWidget { final String label; final VoidCallback? onPressed; const _AppButtonAction({required this.label, this.onPressed}); @override Widget build(BuildContext context) { return TextButton( onPressed: () { onPressed?.call(); Navigator.of(context).maybePop(); }, child: Text(label), ); } }
修复说明
- 把
myApps改为_myAppsFuture,在initState中初始化,避免每次build重复加载数据。 - 重构
loadMyApps方法,使用普通列表逐个获取应用并添加,逻辑清晰且易维护。 - 完善FutureBuilder的状态判断,增加加载中、错误、无数据的处理场景,提升用户体验。
内容的提问来源于stack exchange,提问作者Florentin Lupascu
相关产品推荐
相关产品推荐

