uniapp中5+ mui的Android端app开发

804 阅读7分钟

1.uniapp升级APP,包含apk整包升级和wgt

*apk包整包更新,要下载所有的文件包含权限模块依赖等,大小在20M+

*wgt包应用资源更新,只更新自己写的代码,根据你代码的多少大小在600k左右

*wgtu应用资源差量升级,只更新自己写的代码改变的那一小部分100k左右(实现起来有点复杂这里不讨论)

场景说明

如果你改了App模块配置,权限配置等这些mainfest.json里面的东西,那么就需要apk包整包升级,如果你只是改了代码里的某个地方的bug,或者增减模块这些,那么只需要更新应用资源包就可以了。

apk打包

1.代码修改完

2.修改mainfest.json中的应用版本名称和应用版本号

3.发行

4.云打包

1、在hbuilderx中改接口域名public.js
2、发行--原生App,制作应用wgt  第二种方式:发行---原生App-查看云打包状态-生成本地打包App资源(R)
3、wgt中的代码压缩,然后打开Android studio,下载Android-police-shell壳导入Android studio中的壳路径下的a
pp-src-main-assets-apps.com.lanfan.gazaapp.www中,
4、打开mainfest.json文件中的{"name":"3.2.33","code":3233}
5、打开build.gradle,然后修改versionCode 3233versionName "3.2.33"   版本名和版本号

wgt打包

1.代码修改完

2.修改mainfest.json中的应用版本名称和应用版本号

3.发行

4.制作应用wgt包

*********************************************************************************

整体流程:
1.uni-app打包成App,使用plus.runtime.getProperty方法获取本地应用资源版本号。
2.调用后端接口,拿到与后端规定好的版本号,与前面获取的版本号进行对比,如果不一致(也可以判断当前版本号是否小于线上版本号,也就是最新版本号),进行下一步操作。
3.uni.showModal弹出下载提示。
4.使用plus.downloader.createDownload下载安装包。下载完可以使用plus.runtime.openFile(path),打开文件安装。
5.另一种方法是去浏览器下载,使用plus.runtime.openURL(url); 打开一个网址去下载。
6.推荐的方法是使用wgt热更新,这样就不用每次更改都需要对ios包进行加签。这种方法着重记一下。

AVD Manager-Android虚拟驱动管理器

AVD Manager是一个Android虚拟驱动管理器,主要用来创建安卓模拟器(即手机模拟器)。当然,安卓模拟器所需的镜像(可以理解成模拟器的操作系统)是通过SDK Manager来下载的

一、模拟器配置1.双击启动AVD Manager,进入配置界面2.点Create按钮创建3.配置模拟器基本信息--AVD Name:设备名称,自己定义一个,用英文(不要用中文)--Device:设备型号,如下图选项意思是,4.7寸手机,768*1280分辨率,屏幕密度:xhdpi--Target:选对应API版本号,Android版本号4.4.2,对应API版本19--CPU/ABI:cpu型号--Keyboard:这个最好勾选,带键盘按钮--Skin:皮肤设置,随意设置--Front Camera:前置摄像头,设置为None--Back Camera:后置摄像头,设置为None--Memory Option :RAM运行内存,设置512就行,VM Heap这个是app的运行内存默认设置的64就行--Internal Storage:手机本身的存储卡大小--SD Card:外部SD卡的内存

4、启动模拟器1.选中上面创建成功的模拟器,点start按钮,然后点Launch按钮就能启动了

HbuilderX连接夜神模拟器进行app调试

1.先启动夜神模拟器,打开设置,找到“开发者选项”,(没有“开发者选项的道友”,打开“关于平板电脑”,点击版本号5次即可开启),里面有个USB调试

将它启动就行了,下一步就是启动HbuilderX(模拟器别关就行)

二、打开HbuilderX后,找到设置,打开运行配置(一般的找到步骤:工具=>设置=>运行配置)

三、开始配置模拟器

1、adb路径配置:打开夜神模拟器的安装目录,一般是在Nox/bin目录下面,找到了nox_adb.exe后,将路径指向它就行

 2、端口配置:夜神模拟器我一般设置“62001”,其它的端口也行(只要你填的端口没被占用),后面就要用夜神的nox_adb.exe根据端口号连接了

 四、上面我们找到了nox_adb.exe的文件目录,这次再打开这个目录,在这个目录下启动终端(鼠标点停在目录空白处,shift+鼠标右键,一般有个终端选项,只要有终端,并且目录对的上就行)

 开始输入命令(如果终端目录不一样的话,“./nox_adb.exe”改成相对路径或者绝对路径也行,反正路径能找到程序就行,至于端口号,一定要写成HbuilderX里配置的端口号。如果不行的话,那就重新配置Hbuilder端口号,终端再连接)

1

./nox_adb.exe connect 127.0.0.1:62001

Enter后,如果终端出现下面的情状,那就是连接成功了,如若没有,Hbuilder换端口号

*************************************************************************************

代码

mdLoading是自己写的一个提示

// 获取最新版本信息
		getVersion() {
			let that = this;
			// #ifdef APP-PLUS
			uni.showLoading({
				title: '正在获取最新版本信息...'
			});
			//这里用setTimeout模拟请求
			setTimeout(() => {
				uni.hideLoading();
				let onLineVersion = 105;
				//这里通过请求接口判断版本
				// onLineVersion > plus.runtime.versionCode
				if (true) {
					uni.showModal({
						title: '发现新版本是否升级?',
						content: `
							1、新增个人信息模块
							2、新增版本信息模块
						`,
						success(res) {
							if (res.confirm) {
								that.content = '下载中...'
								that.$refs.mdLoading.show()
								let downloadTask = uni.downloadFile({
									// url: 'http://xxxxxx:8081/xxxxxx.wgt',
									//这个地址是请求后台接口返回的
									url:'http://xxxxxxxx:8081/xxxxxx.apk',
									success(downloadResult) {
										
										if (downloadResult.statusCode === 200) {
											that.content = '下载完成,安装中...'
											plus.runtime.install(
												downloadResult.tempFilePath,
												{
													force: true
												},
												function() {
													that.content = '应用更新完成稍后将重启应用'
													setTimeout(() => {
														that.$refs.mdLoading.hide()
														plus.runtime.restart();
													}, 1000);
												},
												function(e) {
													uni.showToast({
														icon: 'none',
														title: e
													});
												}
											);
										}else{
											that.content = '应用下载失败'
											that.$refs.mdLoading.hide()
										}
									},
									fail(e){
										that.content = e
										setTimeout(()=>{
											that.$refs.mdLoading.hide()
										},1000)
									}
								});
								
								// 监听下载进度
								downloadTask.onProgressUpdate((e)=>{
									that.content = '下载中...'+ e.progress + ' %';
								})
							}
						}
					});
				} else {
					uni.showToast({
						icon: 'none',
						title: '当前已经是最新版本'
					});
				}
			}, 1000);
			// #endif
		}

mdloading文件

<template>
	<view>
		<view v-show="visible" class="fy-loading flex justify-center">
			<view class="box flex flex-column align-center">
				<view class="loading">
					<image  src="/static/loading.gif"></image>
				</view>
				<view class="content">{{content}}</view>
			</view>
		</view>
	</view>
	
</template>

<script>
	export default{
		name:'fy-loading',
		props:{
			content:{
				type:String,
				default:''
			}
		},
		data() {
			return {
				visible: false
			}
		},
		methods:{
			show(){
				this.visible = true;
			},
			hide(){
				this.visible = false;
			}
		}
	}
</script>

<style scoped lang="scss">
	.fy-loading{
		position: fixed;
		left:0;
		top:0;
		right:0;
		bottom:0;
		width:100vw;
		height: 100vh;
		z-index:100;
		background: rgba(0,0,0,0.6);
		overflow: hidden;
	}
	.box{
		width:100px;
		height: 70px;
		margin-top:30vh;
	}
	.content{
		color:#fff;
		font-size:14px;
		text-align:center;
		margin-top:10px;
	}
	.loading{
		width:40px;
		height: 40px;
	}
	.loading image{
		width:100%;
		height: 100%;
	}
</style>


// 检测更新版本
		function checkUpdate() {
			let _this = this;
			this.getVersionSyc(function(obj) {
				mui.ajax({
					url: serverConfig.url + "/app/appVersion/getCurVersion",
					type: "post", //andriod是1,热更新是2
					data: {
						// appType: '1',
					},
					timeout: 15000, //超时
					success: function(data) {
						// alert(JSON.stringify(data))
						// 使用返回的版本号和获取到此时的版本号做对比,如果大于就更新			
						let versionCode = data.versionCode.split('.').join("");
						if (Number(versionCode) > Number(obj.versionCode)) {
							localStorage.setItem("update", '1')
							// _this.isUpdate(data.downloadLink, 'apk'); //更新
							var btnArray=["确定","取消"]
							mui.confirm('发现新版本是否升级?',btnArray,function (e) {
								// 1是确定
								if(e.index==0){
									_this.isUpdate(data.downloadLink, 'apk'); //更新
								}else{
									// 0是取消
								}
							})
						}else{
							localStorage.setItem("update", '0')
							mui.toast("当前已经是最新版本了!")
						}
					}
				})
			})
		}

		// 获取版本号
		function getVersionSyc(callback) {
			var _this = this;
			if (plus) {
				// 获取本地应用资源版本号  
				plus.runtime.getProperty(plus.runtime.appid, (wgtinfo) => {
					versionCode = wgtinfo.versionCode; //应用版本号
					if (callback) {
						callback(wgtinfo);
					}
				})
			}
		}

		// 是否更新
		function isUpdate(obj, type) { // 是否更新
			// let _this = this;
			this.download(obj, type);
		}

		// 下载版本
		function download(path, type) {
			let _this = this;
			plus.nativeUI.showWaiting("发现新版本,正在更新...");
			plus.downloader.createDownload(path, {
				filename: "_doc/update/",
				options: {
					timeout: 3
				}
			}, function(d, status) {
				if (status == 200) {
					_this.installWgt(d.filename); // 安装wgt包
				} else {
					plus.nativeUI.alert("下载文件失败!");
				}
				plus.nativeUI.closeWaiting();
			}).start();

		}

		function installWgt(path) {
			console.log(path)
			plus.nativeUI.showWaiting("正在安装...");
			plus.runtime.install(path, {}, function() {
				plus.nativeUI.closeWaiting();
				// alert("安装成功!")
				plus.nativeUI.alert("已升级最新版,正在重启!", function() {
					plus.runtime.restart();
				});
			}, function(e) {
				plus.nativeUI.closeWaiting();
				// [" + e.code + "]:
				// alert("安装失败"+e.message)
				plus.nativeUI.alert("安装文件失败" + e.message);
			});
		}

2.webview的理解

在html5plus的官方文档中关于webview的方法并不多

 all    获取所有webview窗口 
close    关闭webview窗口 
create  创建新的webview窗口 
currentWebview  获取当前窗口的webviewObject对象(这个对象很重要!!) 
getWebviewById  查找指定表示的webviewObject窗口 
hide    隐藏webview窗口 
open     创建并打开webview窗口 
show      显示webview窗口

3.mui.fire()的用法

作用:
mui.fire()可以触发目标窗口的自定义事件
mui.fire() 目标窗口的webview,‘自定义事件’,{参数列表})
目标窗口监听这个自定义事件   
window.addEventListener('自定义事件名'function(){

})

plus.webview.getLaunchWebview() 获取应用首页WebviewObject窗口对象

4.mui组件使用

在app开发中,若要使用HTML5+扩展api,必须等plusready事件发生后才能正常使用,mui将该事件封装成了mui.plusReady()方法,涉及到HTML5+的api,建议都写在mui.plusReady方法中。

mui.plusReady(function(){
    
})

5.移动开发框架mui之mui.preload预加载后的几种显示方式

preload_home.html(预加载的首页)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <title></title>
    
    <link href="css/mui.min.css" rel="stylesheet"/>  
</head>
<body>
	<button type="button" id="btn_open">打开预加载的页面</button>
</body>
<script src="js/mui.min.js"></script>
<script type="text/javascript" charset="utf-8">
      	mui.init();
		var page=null;
		mui.plusReady(function(){
			// 预加载页面mui.preload必须放在plusReady事件中
			page=mui.preload({
				url:'preload_sub.html',
				id:'preload_sub',
				extras:{
					name:'durant'
				}
			})
		})
		
		document.getElementById("btn_open").addEventListener('tap',function(){
			// 预加载仅会提前创建webview,并不会默认打开,因此需要再使用
			// mui.openWindow方法打开相应窗口,才会看到预加载效果
			if(page){
				// 方法1:直接调用预加载页面对象page中的show方法
				// page.show();
				
				// 方法2:mui.openWindow
				// mui.openWindow("preload_sub");//简写,通过ID打开指定页面
				mui.openWindow({
					url:'preload_sub.html',
					id:'preload_sub'
				})//亦可写详细的参数
				
				// 方法3:getWebviewById(),通过ID找到webview,再调用show()方法
				var wv=plus.webview.getWebviewById("preload_sub");//请在plus ready后再调用plus api,不一定非得写在plusReady事件中
				wv.show()
			}
		})
    </script>
</html>