RK平台Uniapp自启动缓存问题解决
前言
RK
平台上,封装的原生Android
SDK
给客户Uniapp
嵌入调用,给安装的Uniapp
设置开机自启动,因为使用环境的限制,更新Uniapp
时,不能卸载,不能清除App
缓存,只能通过U盘覆盖安装。但是当更新版本后,设备开机自启动跳转了旧版本的主页。
问题分析
此问题分析怀疑可能是以下两点原因:
1、RK
平台上自启动模式机制有问题,第一次设置App
开机自启,可能是将App
的路径和hash
值写入到了某些脚本,Uniapp
更新时候,无法将其安装覆盖,脚本里调用的是安装时生成的固定路径(或者旧的安装路径 hash
)。
2、是Uniapp
打包方式或运行框架机制,UniApp
的 Android
应用本质上是一个 壳 app (wrapper),里面通过一个 WebView
+ JS
引擎 加载你的业务逻辑,当通过 U 盘覆盖安装时,系统确实替换了新的 base.apk
,但 uniapp
的离线资源、自启动注册信息仍然在以下路径。
/data/data/com.xxx.xxx/apps/__UNI__xxxxxx/
而这个路径不会被覆盖更新!所以仍然加载旧的配置和启动逻辑。
问题验证
分析完需求后,逐步验证上述猜想。
猜想1:
1、安装新版本UniApp
后,查看旧版本是否还存在。
检查/data/app
目录下,查看旧版本的Uniapp
已经不存在了,说明已经覆盖安装。
2、使用原生测试App
验证是否和Uniapp
情况一致
原生Android
编写测试代码,打成TestApk1和TestApk2,两个Apk页面内容做区分,先安装TestApk1,设置开机自启动。再使用U盘安装TestApk2后重启,发现现象是正常的,和Uniapp
有差异
猜想2:
查看Uniapp
安装应用数据目录
UniApp
在安装时会解压资源文件到/data/data/com.xxx.xxx/apps/__UNI__4992AC7/目录
# 清理UniApp相关目录
rm -rf /data/data/com.xxx.xxx/apps/__UNI__4992AC7/*
rm -rf /data/data/com.xxx.xxx/apps/.md5
rm -rf /data/data/com.xxx.xxx/files/.md5
rm -rf /data/data/com.xxx.xxx/cache/*
rm -rf /data/data/com.xxx.xxx/code_cache/*
尝试使用上述指令清除缓存,执行完毕后,安装新版本Uniapp
,发现设备重启后,自启动打开的是新版本页面,问题的原因就找到了。
制作Android App
为了方便客户操作,需要开发App,点击按钮后就能完成清除Uniapp
缓存,实现和adb指令一样的效果。因为有系统签名,不需要权限申请等操作,这里只贴出清除资源文件的代码。
private const val TARGET_PACKAGE = "com.xxx.xxx"private fun executeCleanCommands(): Boolean {return try {val process = Runtime.getRuntime().exec("su")val outputStream = DataOutputStream(process.outputStream)val appDataDir = "/data/data/$TARGET_PACKAGE"// 1. 停止应用Log.d(TAG, "停止应用...")outputStream.writeBytes("am force-stop $TARGET_PACKAGE\n")outputStream.flush()Thread.sleep(2000)// 2. 只清理UniApp的www资源目录,保留其他文件Log.d(TAG, "清理UniApp资源...")// 清理所有UniApp目录中的www文件夹内容(这是UniApp的主要资源目录)outputStream.writeBytes("find $appDataDir/apps/__UNI__*/www -type f -delete 2>/dev/null\n")outputStream.flush()// 清理js文件缓存outputStream.writeBytes("find $appDataDir/apps/__UNI__*/js -type f -delete 2>/dev/null\n")outputStream.flush()// 清理css文件缓存outputStream.writeBytes("find $appDataDir/apps/__UNI__*/css -type f -delete 2>/dev/null\n")outputStream.flush()// 清理静态资源缓存outputStream.writeBytes("find $appDataDir/apps/__UNI__*/static -type f -delete 2>/dev/null\n")outputStream.flush()// 3. 清理特定的缓存文件,但不删除数据库和配置Log.d(TAG, "清理特定缓存...")val safeCleanCommands = listOf(// 只清理apps目录下的缓存文件,不清理整个目录"rm -f $appDataDir/apps/.md5 2>/dev/null","rm -f $appDataDir/files/.md5 2>/dev/null",// 清理系统缓存目录,但不影响数据库"rm -rf $appDataDir/cache/* 2>/dev/null","rm -rf $appDataDir/code_cache/* 2>/dev/null",// 清理WebView缓存"rm -rf $appDataDir/app_webview/* 2>/dev/null",// 特别注意:不删除这些目录,只清理特定缓存文件"# 保留数据库: $appDataDir/databases/","# 保留配置: $appDataDir/shared_prefs/")safeCleanCommands.forEach { command ->if (!command.startsWith("#")) {outputStream.writeBytes("$command\n")outputStream.flush()}}Log.d(TAG, "执行温和缓存清理...")outputStream.writeBytes("pm trim-caches $TARGET_PACKAGE 2>/dev/null\n")outputStream.flush()// 5. 修复权限Log.d(TAG, "修复权限...")outputStream.writeBytes("chmod -R 755 $appDataDir 2>/dev/null\n")outputStream.flush()outputStream.writeBytes("exit\n")outputStream.flush()val result = process.waitFor()Log.d(TAG, "精确清理完成,退出码: $result")result == 0} catch (e: Exception) {Log.e(TAG, "执行精确清理命令失败", e)false}}
上述指令用于查找和清除Uniapp
的旧的Web
资源文件,新版本安装后生成新的资源文件,这样就能彻底解决这个问题。
find $appDataDir/apps/__UNI__*/www -type f -delete 2>/dev/null
在UniApp
的 www
目录中,通常会包含:
www/
├── index.html # 主页面文件
├── css/
│ ├── app.css # 样式文件
│ └── chunk-*.css # 代码块样式
├── js/
│ ├── app.js # 主应用逻辑
│ ├── chunk-*.js # 代码块文件
│ └── runtime.js # 运行时文件
├── static/
│ ├── images/ # 图片资源
│ ├── fonts/ # 字体文件
│ └── icons/ # 图标文件
└── manifest.json # 应用配置
总结
~