RK平台Uniapp自启动缓存问题解决

前言

RK平台上,封装的原生Android SDK给客户Uniapp嵌入调用,给安装的Uniapp设置开机自启动,因为使用环境的限制,更新Uniapp时,不能卸载,不能清除App缓存,只能通过U盘覆盖安装。但是当更新版本后,设备开机自启动跳转了旧版本的主页。

问题分析

此问题分析怀疑可能是以下两点原因:

1、RK平台上自启动模式机制有问题,第一次设置App开机自启,可能是将App的路径和hash值写入到了某些脚本,Uniapp更新时候,无法将其安装覆盖,脚本里调用的是安装时生成的固定路径(或者旧的安装路径 hash)。

2、是Uniapp打包方式或运行框架机制,UniAppAndroid 应用本质上是一个 壳 app (wrapper),里面通过一个 WebView + JS 引擎 加载你的业务逻辑,当通过 U 盘覆盖安装时,系统确实替换了新的 base.apk,但 uniapp 的离线资源、自启动注册信息仍然在以下路径。

powershell 复制代码
/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/目录

powershell 复制代码
# 清理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指令一样的效果。因为有系统签名,不需要权限申请等操作,这里只贴出清除资源文件的代码。

kotlin 复制代码
    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资源文件,新版本安装后生成新的资源文件,这样就能彻底解决这个问题。

powershell 复制代码
find $appDataDir/apps/__UNI__*/www -type f -delete 2>/dev/null

UniAppwww 目录中,通常会包含:

php 复制代码
www/
├── index.html          # 主页面文件
├── css/
│   ├── app.css         # 样式文件
│   └── chunk-*.css     # 代码块样式
├── js/
│   ├── app.js          # 主应用逻辑
│   ├── chunk-*.js      # 代码块文件
│   └── runtime.js      # 运行时文件
├── static/
│   ├── images/         # 图片资源
│   ├── fonts/          # 字体文件
│   └── icons/          # 图标文件
└── manifest.json       # 应用配置

总结

~

相关推荐
消失的旧时光-194315 分钟前
Android 面试高频:JSON 文件、大数据存储与断电安全(从原理到工程实践)
android·面试·json
dalancon1 小时前
VSYNC 信号流程分析 (Android 14)
android
dalancon1 小时前
VSYNC 信号完整流程2
android
dalancon1 小时前
SurfaceFlinger 上帧后 releaseBuffer 完整流程分析
android
用户69371750013842 小时前
不卷AI速度,我卷自己的从容——北京程序员手记
android·前端·人工智能
程序员Android3 小时前
Android 刷新一帧流程trace拆解
android
不是株3 小时前
Redis(入门篇)
数据库·redis·缓存
墨狂之逸才3 小时前
解决 Android/Gradle 编译报错:Comparison method violates its general contract!
android
阿明的小蝴蝶4 小时前
记一次Gradle环境的编译问题与解决
android·前端·gradle
qq_281684214 小时前
Apt-Serve:基于混合缓存与自适应调度突破LLM推理KV缓存瓶颈,吞吐量提升8.8倍
缓存