1***@qq.com
1***@qq.com
  • 发布:2026-01-24 14:57
  • 更新:2026-01-24 14:58
  • 阅读:25

Andorid系统,app 开机自启,版本回退

分类:uni-app

app开机自启时,/sdcard未挂载上时,在 /data/data/包名/apps 上读取manifest.json,导致版本回退。自启在 /sdcard挂载上之后时,读取的是 /data/data/包名/files/apps 下的manfiest.json,版本正常

2026-01-24 14:57 负责人:无 分享
已邀请:
Ask小助手

Ask小助手 - Ask社区AI助手

该问题请在专业群( uni-app 官方技术交流群 1 ) 咨询,群中有相关专业的管理员和群友。

问题本质
在 Android 11 及以上系统,/sdcard(外部存储)采用「分区存储」+「延迟挂载」策略。
开机后如果 App 被系统或第三方保活工具立即拉起,此时外部存储尚未挂载完成,
uni-app 热更新框架(wgt-loader)会退而求其次去 /data/data/包名/apps/manifest.json 读取版本信息;
而当外部存储可用后再启动,框架会优先读取 /data/data/包名/files/apps/manifest.json(指向 /sdcard 上的 wgt 包)。
两份 manifest.json 版本号不一致就会出现「版本回退」。

解决思路

  1. 让框架在 /sdcard 挂载完成以后再执行热更新检测。
  2. 或者把热更新包直接放到内部存储,彻底摆脱外部存储挂载时机。

推荐做法(uni-app 可落地)

  1. 延迟执行热更新
    App.vue → onLaunch 里,先监听外部存储挂载事件,再调用 plus.runtime.install:

    // #ifdef APP-ANDROID  
    function waitForExternalStorage() {  
     return new Promise((resolve) => {  
       const path = plus.io.convertLocalFileSystemURL('_doc/');  
       const timer = setInterval(() => {  
         plus.io.resolveLocalFileSystemURL(  
           path,  
           () => {  
             clearInterval(timer);  
             resolve(true);  
           },  
           () => {}  
         );  
       }, 200);  
     });  
    }  
    
    onLaunch: async function () {  
     await waitForExternalStorage();      // 等 /sdcard 就绪  
     // 再执行热更新逻辑  
     plus.runtime.getProperty(plus.runtime.appid, (info) => {  
       // 这里再读取 /sdcard 上的 manifest.json  
     });  
    }  
    // #endif  
  2. 把 wgt 包放到内部存储
    在 manifest.json → app-plus → distribute → android 里加

    "android": {  
     "wgtPath": "/data/data/__PACKAGE_NAME__/files/apps"  
    }  

    然后在服务器端把 wgt 包下载到 plus.io.convertLocalFileSystemURL('_doc/apps/')(内部存储),
    这样无论外部存储是否挂载,读取的都是同一份文件,不会出现版本差异。

  3. 使用系统广播(可选)
    如果项目里已经接入了原生插件,可以在 AndroidManifest.xml 注册监听

    <receiver android:name=".BootReceiver">  
       <intent-filter>  
           <action android:name="android.intent.action.MEDIA_MOUNTED" />  
           <data android:scheme="file" />  
       </intent-filter>  
    </receiver>  

    收到广播后再通过 UniJSCallback 通知 uni 层开始热更新。

  4. 关闭第三方保活/自启
    某些保活框架会在系统启动 1-2 秒内强行拉起 App,导致 100% 复现。
    在设置里关闭「自启动」或把热更新逻辑延后到 onShow 第一次进入前台时再执行,也能规避。

小结
最简方案:在 onLaunch 里加 2-3 秒延时或轮询 /sdcard 是否可用,再读取 manifest.json;
根治方案:把 wgt 包放到内部存储,彻底摆脱外部存储挂载时序问题。

内容为 AI 生成,仅供参考

要回复问题请先登录注册