彻底解决Flutter_downloader中出现的问题
如果本文未能解决你的插件问题,请查看文章最底部另外一款插件的使用
由于之前已经发布过一篇文章Flutter内部更新遗留了一些问题就是关于Flutter_downloader报错的问题,错误原因是
一开始挺摸不着头脑的,最近新的项目又涉及到了FlutterAPP
内部更新问题,因为上次的失败,所以这次决定一定要解决掉,虽然又是和上次一样报了
'package:flutter_downloader/src/downloader.dart': Failed assertion: line 388 pos 12: 'callbackHandle != null'
开始检查代码和项目,首先发现第一个问题,状态栏已经触发下载方法了,但是状态为failed
,也就是说明,插件的下载方法没有问题,但是没有下载成功。这是为什么呢??
错误原因:
由于我是用的本地映射网络,HTTP的请求下载方法,因为Android和IOS都有限制,禁止随便下载HTTP和访问HTTP的内容,具体原因和Flutter内部访问WebView出现net:ERR_CLEARTEXT_NOT_PERMITTED
原因一致,所以只需要配置允许HTTP请求访问即可。
解决办法:
1、打开你的项目,在android/app/src/main/res目录下创建目录xml,随后创建xml文件network_security_config.xml
具体代码
:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
2、打开你的AndroidManifest.xml
这个配置文件,加上下面这一行
android:networkSecurityConfig="@xml/network_security_config"
这个问题便可以解决了。
第二个问题
'callbackHandle != null'的错误原因
其本质原因就在于之前写监听下载方法registerCallback
的时候忽略了文档上的这个要求,并且没有声明为static
静态方法,所以才会导致这个问题的出现。
解决办法
只需要将方法抽离出来,并且声明为静态方法便可以了。
@override
void initState() {
super.initState();
// clear();
judgePhoneInfo();
_checkPermission();
createFile();
FlutterDownloader.registerCallback(downloadCallback);
}
// id:下载id status:下载状态 progress:下载进度
// 可用DownloadTaskStatus.failed == status 与 DownloadTaskStatus.complete == status 来判断失败与完成
static void downloadCallback(id, status, progress){
print('Download task ($id) is in status ($status) and process ($progress)');
}
下图为监听进度
这样所有问题便可以得到解决了。
2022.5.30更新
换插件了兄弟们! Flutter_downloader不行的,可以使用另外一款插件ota_update
亲测好用!!
使用方法:
/// 检查当前版本是否为最新,若不是,则更新
void _checkVersionCode() async {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
api.getData(context, 'upgrade_init').then((v) {
if (v != null) {
String version = packageInfo.version;
// v['data']['version'] 为后端返回的最新版本
var isUpdate = haveNewVersion(v['data']['version'], version);
if (isUpdate) {
// v['data']['path'] 为后端返回的服务器apk路径
_showNewVersionAppDialog(v['data']['path']);
}
}
});
}
// 比较版本号判断是否更新
bool haveNewVersion(String newVersion, String old) {
if (newVersion == null || newVersion.isEmpty || old == null || old.isEmpty)
return false;
int newVersionInt, oldVersion;
var newList = newVersion.split('.');
var oldList = old.split('.');
if (newList.length == 0 || oldList.length == 0) {
return false;
}
for (int i = 0; i < newList.length; i++) {
newVersionInt = int.parse(newList[i]);
oldVersion = int.parse(oldList[i]);
if (newVersionInt > oldVersion) {
return true;
} else if (newVersionInt < oldVersion) {
return false;
}
}
return false;
}
/// 版本更新提示对话框
Future<void> _showNewVersionAppDialog(path) async {
// 显示提醒更新UI界面, 读者自行开发一下哈~
return UpdateWidget(path);
}
/// 执行更新操作
// 接收的path是UI界面中传入的path
static doUpdate(BuildContext context, path) async {
try {
// destinationFilename 是对下载的apk进行重命名
var destinationFilename = path.toString().substring(path.toString().lastIndexOf('/') + 1);
OtaUpdate().execute(
path,
destinationFilename: destinationFilename,
// headers:{},
).listen(
(OtaEvent event) {
try{
switch (event.status) {
case OtaStatus.DOWNLOADING: // 下载中
print('status:${event.status},value:${event.value}');
break;
case OtaStatus.INSTALLING: //安装中=
break;
case OtaStatus.PERMISSION_NOT_GRANTED_ERROR: // 权限错误
break;
default: // 其他问题
break;
}
}catch(e){
print('错误:$e');
}
},
);
} catch (e) {
print('更新失败');
}
}
有问题请在下方留言~