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 的离线资源、自启动注册信息仍然在以下路径。

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

在UniApp的 www 目录中,通常会包含:

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

总结

~

相关推荐
千里马学框架4 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台4 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone4 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc4 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo4 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077004 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
全栈弄潮儿²⁰²⁴4 天前
AI Agent 开发实战(30):限流、缓存与成本控制
人工智能·gpt·缓存·agent·限流·agi·成本控制
其实防守也摸鱼4 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
码兄科技4 天前
24小时自助健身房系统软件开发实战指南:功能设计与部署方案
java·spring boot·uni-app
AFinalStone4 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui