赞
踩
uni-app App段内置了一个基于weex改进的原生渲染引擎,提供了原生渲染能力。
在App端,如果使用vue页面,则使用webview渲染;如果使用nvue页面(native vue的缩写),则使用原生渲染。一个App中可以同时使用两种页面,比如首页使用nvue,二级页使用vue页面,hello uni-app示例就是如此;
虽然nvue也可以多端渲染,输出H5和小程序,但nvue的css写法受限,所以如果你不开发App,那么不需要使用nvue。
原生 > Flutter > RN > Uniapp
原生 > RN > Uniapp >Flutter
原生 > Flutter > RN > Uniapp(但其实随着hooks的入场,RN的学习成本和Uniapp差距不大了)
**【flutter】**根据google推出的flutter sdk进行编写,完全颠覆了android的开发理念,须知道,android、flutter都是google的, android开发使用的android sdk,flutter却不然,自制了一套自己的sdk,直接使用GPU渲染机制,在用户手机上 非常直接的 canvas draw view,其手段已经非常nx。
【reactNative】 的bridge(桥接)技术也是很厉害的!他通过了android 与 js之间构成了bridge,中间经过了编译,最终进行了android控件转换,这点有些像javac编译class那一块了,最终绘制在用户手机上的是原生控件。其中性能问题并不算太大,因为得到的是原生页面,所以比较受欢迎。
相对比下来 rn中间那层转换编译 对于 flutter来说是没有的,相对来说flutter是最直接的,但这里我也要指出,对于目前用户手机性能来说,现在android已经到11了,中间那部分转换损耗的性能,用户基本是感知不到的.
**【uniapp】**当前这个框架采用vue,采用云打包的方式生成apk发布使用.
这个框架我并不看好,开发者可以打开布局边界查看下布局,其中完全使用网页的形式呈现给用户,基本跟android不怎么挂钩,即便挂钩,官方也已经作出了api供用户使用.
虽然说完全使用网页的形式制作,但性能方面不至于太差劲,因为官方做出了很多网页的优化,具体性能暂时劣势于flutter,reactNative。
新建步骤:文件>新建>项目
新建完成后,目录如下:
pages.json等同于微信小程序中的app.json,用于配置路由等基本配置。
正常的界面调试可以在HBuildX
中,通过预览来调整。但是微信api需要在微信模拟器宿主中才能正常调用。所以我们需要把代码运行到微信小程序模拟器。
平台会将代码做编译打包成微信小程序代码,并且启动热更新模式。并且会创建一个unpackage
目录,里面存放了编译后的代码。
然后我们需要使用微信小程序开发者工具,导入mp-weixin
项目。
打开pages/index/index.vue
,页面交互设计是这样的:
拍照或者相册选择图片
将图片提交百度AI识别物体信息
根据百度AI返回的照片物体信息,判断物体属于哪类垃圾
下面先实现步骤1,修改template
代码为:
<template> <view class="content"> <button type="primary" @click="btnTaskPhoto">识别通用物体</button> <img :src="imageSrc" alt=""> </view> </template> <script> export default { data() { return { imagePath: "", imageSrc: "" } }, onLoad() { }, methods: { btnTaskPhoto() { uni.chooseImage({ count: 1, success: (res) => { console.log(res); this.imagePath = res.tempFilePaths[0]; this.images2base64(); } }); }, images2base64() { wx.getFileSystemManager().readFile({ filePath: this.imagePath, encoding: "base64", success: (res) => { this.imageSrc = 'data:image/png;base64,' + res.data console.log(res); } }) } } } </script> <style> .content { display: flex; flex-direction: column; align-items: center; justify-content: center; } </style>
显示如图:
打开小程序开发者工具,我们进行调试,如下:
上传成功后,图片显示到页面上:
首先进入百度智能云并注册账号,选择产品>人工智能应用>图像识别。
然后进入应用列表,创建一个应用。创建完成后,可以拿到应用的API Key
和Secret Key
。
然后通过鉴权认证接口拿到access token。
https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=【百度云应用的AK】&client_secret=【百度云应用的SK】
调用通用物体和场景识别API。修改images2base64
方法:
images2base64() { wx.getFileSystemManager().readFile({ filePath: this.imagePath, encoding: "base64", success: async (result) => { this.imageSrc = 'data:image/png;base64,' + result.data; // 获取accexx_token const params = { 'client_id': 'llwgkZX3f5hYcP2xiaK7ewdf',//自己的Api Key 'client_secret': 'GaQgeSPhjX8Sv21uAxG0G3NpGGVELvYn'//自己的Secret Key }; const res1 = await uni.request({ url: `https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=${params.client_id}&client_secret=${params.client_secret}` }) const { access_token } = res1.data; // 提交图片到百度AI,识别 const res2 = await uni.request({ method: "POST", url: `https://aip.baidubce.com/rest/2.0/image-classify/v2/advanced_general`, header: { "Content-Type": "application/x-www-form-urlencoded" }, data: { access_token: access_token, image: encodeURI(result.data) } }) console.log(res2); } }) }
然而提示报错:Open api qps request limit reached
尝试再次识别时,已经有识别的结果:
//调用,res2是百度识别的结果
this.parseResult(res2.data.result);
//添加methods
parseResult(result) {
let itemList = result.map(item => item.keyword + item.score);
uni.showActionSheet({
itemList: itemList
})
}
页面显示如下:
进入到uni-cloud后端服务空间列表管理界面,点击【新建服务空间】,弹窗新建弹窗,可选择阿里云和腾讯云,阿里云每个账号可以创建一个免费服务空间。如图:
这里创建阿里云空间。
然后返回HBuilderX
,右键uniCloud
目录,点击【关联云服务空间或项目】
关联成功后,uniCloud
目录右侧会出现关联的云服务空间的名称。
在uniCloud
目录右键单击,选择新建云函数/云对象
。
uniCloud
目录下会多出一个ImageClassify
目录,里面有index.js
、package.json
两个文件。类似微信的小程序文件结构;
/ImageClassify/index.js
代码如下:
'use strict'; exports.main = async (event, context) => { const params = { 'client_id': 'llwgkZX3f5hYcP2xiaK7ewdf', 'client_secret': 'GaQgeSPhjX8Sv21uAxG0G3NpGGVELvYn' }; // 获取accexx_token const res = await uniCloud.httpclient.request( `https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=${params.client_id}&client_secret=${params.client_secret}`, { method:"GET", dataType: "json", } ) const access_token = res.data.access_token; // 提交图片到百度AI,识别 let res2 = await uniCloud.httpclient.request( "https://aip.baidubce.com/rest/2.0/image-classify/v2/advanced_general", { method: "POST", header: { "Content-Type": "application/x-www-form-urlencoded" }, dataType: "json", data: { access_token: access_token, image: event.image } }); //返回数据给客户端 return res2.data; };
上传部署:
上传完成后,可以在云服务空间看到云函数:
如果想要做调试,只需要在控制台右上角开启断点调试,再次再请求过来的时候,就会出发云函数中的断点;
修改pages/index/index.vue
中image2base64
方法:
images2base64() { let that = this; wx.getFileSystemManager().readFile({ filePath: this.imagePath, encoding: "base64", success: async (result) => { this.imageSrc = 'data:image/png;base64,' + result.data; uniCloud.callFunction({ name: "ImageClassify", data: { image: encodeURI(result.data) }, success: (res) => { console.log(res); that.parseResult(res.result.result); } }) } }) }, parseResult(result) { let itemList = result.map(item => item.keyword + item.score); uni.showActionSheet({ itemList: itemList }) }
但是在运行的时候提示:应用未关联服务空间,请在uniCloud目录右键关联服务空间
我们需要到HBuilder X
重新运行下。
到小程序模拟器中再次识别的时候已经正常。
查看network可以看到,是访问的本地ip:
可以看到,这时是访问的云端的接口:
条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。所有的东西都可以条件编译;官方文档
// #ifdef APP-PLUS
console.log("我在原生App环境里");
// #endif
// #ifdef MP-WEIXIN
console.log("我在微信小程序环境里");
// #endif
上面在将选择的照片转化成base64时,我们采用wx.getFileSystemManager
,这在ios中时不能正常运行的。这里我们可以使用条件编译,区分不同的环境去跑不同的api。
我们还是修改pages/index/index.vue
:
images2base64() { let that = this; // #ifdef APP-PLUS // html5+.io文档地址:https://www.html5plus.org/doc/zh_cn/io.html plus.io.resolveLocalFileSystemURL(this.imagePath, entry => { entry.file(file => { let reader = new plus.io.FileReader(); reader.onloadend = (e) => { //e.target.result是base64文件编码,注意是带编码头的。所以我们需要去掉编码头(data:image/jpeg;base64,)。 console.log(e.target.result); const base64 = e.target.result.substr(22); //截取掉文件头 uniCloud.callFunction({ name: "ImageClassify", data: { image: base64 }, success: (res) => { console.log(res); that.parseResult(res.result.result); } }) } reader.readAsDataURL(file); }); }) // #endif // #ifdef MP-WEIXIN wx.getFileSystemManager().readFile({ filePath: this.imagePath, encoding: "base64", success: async (result) => { this.imageSrc = 'data:image/png;base64,' + result.data; uniCloud.callFunction({ name: "ImageClassify", data: { image: encodeURI(result.data) }, success: (res) => { console.log(res); that.parseResult(res.result.result); } }) } }) // #endif },
打开:运行>运行到手机或模拟器>运行到IOS基座。首次打开需要安装模拟器插件
在React Native、Flutter,要开发IOS应用,必须要用Mac。
如果我们用uniapp,可以不用mac,因为有云打包,但是不能调试,如果需要调试,还是需要上mac。
打开插件市场,搜索【垃圾分类】
导入插件(这个插件内部借助了第三方http api,搜索判断物体是什么类型的垃圾,目的第三方http api已经弃用,所以这个插件实际已经无效。这里仅做步骤演示用):
页面自动打开Hbuilder X
,给出提示:
点击确认,会将插件下载到本地云函数目录uniCloud
。
然后我们可以手动上传部署。然后我们调整下识别垃圾之后的业务逻辑:
parseResult(result) { if (!result || !result.length) { return null; } this.selectRecResult(result[0].keyword); }, selectRecResult(name) { uniCloud.callFunction({ name: "TrashClassify", data: { keyword: name }, success: (res) => { console.log(res); //拿到区分垃圾分类后的信息,后面可以做相应的业务处理 } }) }
HBuilderX
针对原生app,提供了云打包,如果我们没有mac,要发布ios就可以直接使用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。