uniapp online upgrade (hot update) and java background

        If you too are tired of having to re-download a whole package every time you upgrade, reinstall. Then you can try this hot update solution. In fact, hot update technology is not uncommon on the mobile terminal. Those who did native APP development several years ago should have been exposed to this technology. This time I also used the hot update of uniapp, so record it , which is convenient for direct use later.

        The technology is not difficult, please look down~ 

        First of all, I created a uniapp project without writing any code. Let's take this as a project that has been developed in the actual project, after all, it is just a demonstration. So this version is regarded as version 1.0.0

        

         Ok, then, let's add hot update code to this version 1.0.0.

1. Write hot update code to the old version

        First open the App.vue code in the project and write it in onLaunch, because we hope that when the App starts, it will detect whether there is a new version that needs to be updated. The specific code is as follows:

<script>
	export default {
		onLaunch: function() {
			console.log('App Launch');
			// #ifdef APP-PLUS
			plus.runtime.getProperty(plus.runtime.appid,(widgetInfo)=>{
				console.log(widgetInfo);
				uni.request({
					url:'http://192.168.3.20:8080/UpdateProject/update/check',
					data:{
						versionCode:widgetInfo.versionCode
					},
					success:function(res){
						console.log(res);
						if(res.data.code==0){  
							if(res.data.data.down){    
                            //下载地址根据实际来修改,我这个是拼接前缀的下载地址
								let downUrl="http://192.168.3.20:8080"+res.data.data.down;
								console.log("url:"+downUrl);
								uni.downloadFile({
									url:downUrl,
									success:function(downloadResult){
										if(downloadResult.statusCode==200){
											plus.runtime.install(downloadResult.tempFilePath,{
												force:false
											},function(){
												console.log("安装成功");
												plus.runtime.restart();
											},function(e){
												console.log(e);
												console.log("安装失败...")
											});
										}
									}
								})
							}
						}else{
							console.log("已经是最新版本,无需更新")
						}
					}
				})
			})
			// #endif
		},
		onShow: function() {
			console.log('App Show')
		},
		onHide: function() {
			console.log('App Hide')
		}
	}
</script>

<style>
	/*每个页面公共css */
</style>

The code has been given to you, but let me explain. First of all, // #ifdef APP-PLUS is not a comment, it is called conditional compilation

Conditional compilation (can be used in components, css, js, .json configuration):

A code block that will be compiled or not executed under certain conditions

Syntax: // #condition platform

   condition:

           ifdef : if defined positive condition, which means that it will only compile and take effect under the xxx platform

           ifndef : if not defined reverse condition, which means that it will not take effect under the xxx platform, and it will take effect on other platforms

           endif : end tag, means end of condition

   platform:

           APP-PLUS         will only take effect in the app-side environment

           APP-PLUS-NVUE         will only take effect in the app nvue environment

           H5         will only take effect in the H5 environment

           MP         WeChat Mini Program/Alipay Mini Program/Baidu Mini Program/Toutiao Mini Program/QQ Mini Program

           MP-WEIXIN         will only take effect in the WeChat Mini Program environment

           MP-ALIPAY         will only take effect in the Alipay applet environment

           MP-BAIDU          will only take effect in the Baidu Mini Program environment

           MP-TOUTIAO         will only take effect in the ByteDance applet environment

           MP-360         will only take effect in the 360 ​​applet environment

           MP-QQ           will only take effect in the QQ applet environment

plus.runtime.getProperty(plus.runtime.appid, function(widgetInfo) is to obtain the configuration of the program itself, and obtain the package information through its own appid

widgetInfo contains various package information, including version number and version name

This is the configuration. For example, if we are version 1.0.0, the version number is 100. When we modify the bug or add a new function, we can change the version to 1.0.1 and the version number to 101. In this way, in actual operation, we can know the currently installed version and compare the versions

 Further down, uni.request is a normal request. Remember your current version number, the one with numbers, not the one with dots. Send it to the background, and the background will query the version number of the latest version for comparison. If the version sent is smaller than the version queried in the background, it means that you need to update the version, and the download address will be returned. If the version sent is not less than the version queried in the background , then there is no need to return the download address, I wrote the logic like this.

So if I judge whether the return code is 0,0, it means that it needs to be updated, and then download it when the download address is not empty. After the download is successful, use plus.runtime.install to install

2. Write a new version

        Next, let's write a little code first, that is, in the actual project, after we fix bugs or add new functions, it becomes a new version. Here I simply add a line of code to indicate that a new function has been added

        

         Then go to manifest.json to modify the version information

        

3. Generate wgt package

        We generate the wgt package based on the new version, that is, the upgrade package. Click release to select native App-make application wgt package

         

 

 It is up to you whether to add or not to confuse, adding is safer and prevents decompilation to a certain extent

We can see that the wgt package has been generated.

 4. Java background writing (only for reference, modify the actual project by yourself)

 My background is springboot+layui+mybatis

And I only made a query list, uploaded the wgt package, and checked whether the function needs to be updated

Table Structure:

Controller

@RestController
@RequestMapping("/update")
public class UpdateController {

    //tomcat虚拟路径,上传的wgt存放在这里,实际项目中存放在ftp服务器,或者oss上
    @Value("${upload.filePath}")
    private String filePath;

    @Autowired
    private UpdateService updateService;

    /**
     * 分页查询App版本列表
     * @param page 页码
     * @param limit 每页大小
     * @return 分页后的版本列表数据
     */
    @RequestMapping("/list")
    public ResultTableBean getListByPage(int page,int limit){
        ResultTableBean rtb=new ResultTableBean();
        List<UpdateBean> list = updateService.findUpdateBeanList(page, limit);
        int updateCount = updateService.getUpdateCount();
        rtb.setCode(0);
        rtb.setData(list);
        rtb.setCount(updateCount);
        return rtb;
    }

    /**
     * 检查是否需要更新
     * @param versionCode 版本号
     * @return 结果
     */
    @RequestMapping("/check")
    public ResultBean checkAppNeedUpdate(int versionCode){
        ResultBean rb=new ResultBean();
        UpdateBean updateBean = updateService.checkUpdate(versionCode);
        if (updateBean!=null){
            rb.setCode(0);
            rb.setData(updateBean);
        }else {
            rb.setCode(1);
        }
        return rb;
    }

    @RequestMapping("/add")
    public ResultBean uploadAppVersion(@RequestParam("app") MultipartFile file, UpdateBean bean){
        ResultBean rb=new ResultBean();
        //获取文件名
        String originalFilename = file.getOriginalFilename();
        //获取文件的后缀名
        String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));
        //为了避免同一个文件夹下文件名重复问题,所以随机生成uuid作为文件名
        String fileName= UUID.randomUUID()+suffixName;
        File file1=new File(filePath+fileName);
        try {
            //文件存放到虚拟路径下
            file.transferTo(file1);
            //保存虚拟路径到数据库
            bean.setDown("/appVersion/"+fileName);
            boolean result = updateService.addUpdateBean(bean);
            if (result) {
                rb.setCode(0);
            }else {
                rb.setCode(1);
            }
        } catch (IOException e) {
            e.printStackTrace();
            rb.setCode(2);
        }
        return rb;
    }

}

Service

@Service
public class UpdateServiceImpl implements UpdateService {

    @Autowired
    private UpdateMapper updateMapper;

    @Override
    public List<UpdateBean> findUpdateBeanList(int page, int limit) {
        return updateMapper.findUpdateBeanList((page-1)*limit,limit);
    }

    @Override
    public int getUpdateCount() {
        return updateMapper.getUpdateCount();
    }


    @Override
    public boolean addUpdateBean(UpdateBean bean) {
        int row = updateMapper.addUpdateBean(bean);
        if(row>0){
            return true;
        }
        return false;
    }

    @Override
    public UpdateBean checkUpdate(int versionCode) {
        UpdateBean updateBeanLast = updateMapper.findUpdateBeanLast();
        if (updateBeanLast!=null){
            if (updateBeanLast.getCode()>versionCode){
                return updateBeanLast;
            }
        }
        return null;
    }
}

 Mapper

@Repository
@Mapper
public interface UpdateMapper {

    /**
     * 分页查询版本列表
     * @param start 起始位置
     * @param end 结束位置
     * @return 版本列表
     */
    public List<UpdateBean> findUpdateBeanList(int start,int end);

    /**
     * 获取版本列表总个数
     * @return 总个数
     */
    public int getUpdateCount();

    /**
     * 查询最新的版本
     * @return 最新的版本
     */
    public UpdateBean findUpdateBeanLast();

    /**
     * 新增APP版本
     * @param bean 版本信息
     * @return 受影响的行数
     */
    public int addUpdateBean(UpdateBean bean);
}

Mapper.xml

 <select id="findUpdateBeanList" resultType="com.xxx.update.bean.UpdateBean">
        select *from tb_update order by upload_time desc limit #{param1},#{param2}
    </select>

    <select id="getUpdateCount" resultType="int">
        select count(*) from tb_update
    </select>

    <select id="findUpdateBeanLast" resultType="com.xxx.update.bean.UpdateBean">
        select *from tb_update order by upload_time desc limit 1
    </select>

    <insert id="addUpdateBean" parameterType="com.xxx.update.bean.UpdateBean">
        insert into tb_update values(null,#{name},#{code},#{desc},#{down},now())
    </insert>

 The front-end page code will not be released, it is of little significance

The front-end effect diagram is as follows:

 This is OK, upload this new version package

Effect after upgrade:

 Well, let's come to an end here!

My personal creation, if there is any similarity, it is purely coincidental, or contact me to make changes. Please reprint or CV combination to indicate the source, thank you! (If you have any questions or mistakes, please point them out, my QQ:752231513)

Guess you like

Origin blog.csdn.net/qq_30548105/article/details/125551858