移动端开发相关概念
APP类型
Native APP
Native APP又称原生APP,就是我们平时说的手机应用软件。
原生APP 是针对IOS、Android、Windows等不同的手机操作系统要采用不同的语言和框架进行开发出来的,通常是由“服务器数据+APP应用客户端”两部份构成。
实现技术:
iOS: object-c 或者 swift
Android: java
优缺点
优点:
成品体验好,用户无法上网也可访问APP应用中以前下载的数据
性能稳定,可调用手机的硬件设备(语音、摄像头、短信、GPS、重力感应等)和本地资源(通讯录,相册等)
操作速度快,能够实现出色的动效,转场动画完美
缺点:
开发周期长,开发人员工资起点高。
用户要使用原生APP,必须通过安装到手机里面才行,而且APP软件体积大,占用较多手机内存容量
更新缓慢,根据不同平台,提交–审核–上线流程较复杂。
要获取最新功能,需要升级应用,所以会容易出现有些用户不升级,导致多个不同功能版本出现,维护成本大
跨平台差,每种平台都需要独立的开发语言。Java(安卓),Objective-C(iOS)等等
Web APP
实现技术:
HTML5+Javascript+CSS3
vue组件化
....
优缺点
优点:
一套代码到处运行,可以同时在 PC、Android、iPhone 浏览器*问
开发者不需要发布到应用市场审核,用户不需要下载、安装和更新
开发周期短,维护成本低
用户不需用户手动更新,可以自动更新,直接使用最新版本
缺点:
转场表现略差,要求联网
用户体验没那么炫。图片和动画支持性不高
没法在App Store中下载、无法通过应用下载获得盈利机会
对手机功能应用缺乏,有限制(摄像头、GPS、蓝牙等)
Hybrid APP
Hybrid App就是混合APP,就是Native结合Web的混合开发,就是内部本质是Web网页,使用打包软件给它套一层原生APP的外壳。
实现技术:
React Native
UNIAPP
APICloud
WeX5
appMobi
appcan
phoneGap(cordova+android)
....
优缺点
优点:
集众家之长,既可以调用丰富的手机设备API,也能拥有Web APP的跨平台能力
可以在应用商店发布,实现收费下载
内部是网页结构,可以自主更新,做到开发一次,所有平台生效
降低开发成本和技术成本,降低维护和开发周期
缺点:
本质上就是一个Web APP使用了原生APP的壳,所以体验比不上原生APP
开发难度比Web APP高,有一定的学习成本,开发周期比Web APP长
APP发布有可能无法通过审核,需要多次调整,才能发布
依赖开发框架本身提供的手机设备API,少部分设备功能还是只能借住原生语言进行调用才可以
对团队技术栈要求相对高,既要懂web开发的,也要懂原生APP开发的
移动端自适配方案
所谓的适配方案就是指可以让我们应用的内容可以在不同屏幕尺寸下合理进行展示的方案。
目前常用的布局适配方案就3种,分别是vw
、像素百分比+flex弹性布局
和rem+viewport
,后者最流行最容易。
当然,rem+viewport
这种方案的实现方式也有很多,其中最著名的就是淘宝的flexible方案。
vw
vw是css里面用于表示html元素尺寸的一个相对单位。这个单位是通过把界面窗口横向分割成100列得到的,1vw就1列。
与vw相对的有vh,vh是把界面窗口垂直分成100行,1vh就是1行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.box{
width: 50vw;
height: 50vh;
background: #eee;
}
.son{
width: 50vw;
height: 50vh;
background: red;
}
</style>
</head>
<body>
<div class="box">
<div class="son"></div>
</div>
</body>
</html>
像素百分比+flex弹性布局
flex是css提供给前端开发者,用于平均分布大小的计算属性。可以让我们实现相对的排版布局。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.menu{
width: 100%;
background-color: orange;
}
.menu-list{
width: 90%;
margin: 0 auto;
background: gray;
list-style: none;
padding: 0;
display: flex; /* 设置当前元素为flex弹性容器 */
}
.menu-item{
float: left;
width: 120px;
line-height: 32px;
height: 32px;
/* flex: 1; /* 把整个父元素的宽度尺寸平局分成(1 * 元素)份,每个元素占1份 */
flex: 2; /* 把整个父元素的宽度尺寸平局分成(2 * 元素)份,每个元素占2份 */
}
.menu-item:hover{
flex: 4; /* 在上面设置的基础上,其他兄弟元素占2份,这个元素占4/12份,其他兄弟2/12 */
}
.menu-item:hover a{
background: red;
}
.menu-item a{
text-decoration: none;
font-family: Manjari;
color: dodgerblue;
width: 100%;
font-size: 18px;
display: block;
background: #add;
text-align: center;
}
</style>
</head>
<body>
<div class="menu">
<ul class="menu-list">
<li class="menu-item"><a href="">百度</a></li>
<li class="menu-item"><a href="">京东</a></li>
<li class="menu-item"><a href="">淘宝</a></li>
<li class="menu-item"><a href="">华为</a></li>
<li class="menu-item"><a href="">Oldboy</a></li>
</ul>
</div>
</body>
</html>
rem+viewport
rem是css提供给开发者用于表示元素尺寸的长度单位,是根据html根标签的font-size来计算的单位。
如果html标签设置font-size: 24px;则整个html中,1rem就表示1*24px,2.5rem就是2.5*24px;
有了rem单位以后,我们将来页面需要在不同尺寸在设备下展示时,只需要知道当前设置的尺寸,就可以通过js修改html标签的font-size来适应对应的屏幕了。
viewport就是html元信息里面的一个属性。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scala=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
<title>Title</title>
<style>
.box{
max-width: 100%;
width: 600px;
height: 200px;
background: blue;
color: #fff;
font-size: 16px;
}
</style>
</head>
<body>
<div class="box">hello, world!!!</div>
</body>
</html>
元信息(meta)
html中的meta标签,也叫元信息标签。作用就是用来告诉浏览器,当前网页的附加信息。
meta标签主要有2个属性比较重要。
属性名 | 属性值 | 作用描述 |
---|---|---|
http-equiv | content-type , expires , refresh , set-cookie | 设置 HTTP 头部 |
name | viewport,author , description , keywords | 设置网页附加描述信息 |
例子:
<head>
<meta name="description" content="移动端开发" />
<meta name="keywords" content="移动端,APP,flask" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Refresh" content="5;url=http://www.luffycity.com" />
</head>
视口(Viewport)
视口是一个相对比较复杂的概念,所以我们可以简单的理解为,viewport就是用户看手机页面时的可视区域,相当于桌面浏览器的窗口。在桌面浏览器中,viewport 就是浏览器窗口的宽度高度。但在移动端设备上就有点太窄了。
关于视口的详细扩展知识可以参看:https://www.w3cplus.com/css/viewports.html
视口通过meta标签进行设置
<meta name="viewport" content="width=device-width, initial-scala=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
视口参数说明
属性名 | 属性值 |
---|---|
width | 网页的宽度 |
device-width | 设备的宽度 |
initial-scale | 初始的缩放比例 |
minimum-scale | 允许用户缩放到的最小比例 |
maximum-scale | 允许用户缩放到的最大比例 |
user-scalable | 用户是否可以手动缩放 |
像素(pixel)
在移动端上,所谓的像素分为两种。
CSS像素:CSS像素就是我们在编写CSS代码时的像素。
设备像素:设备屏幕的物理像素,任何设备的物理像素的数量都是固定的。
媒体查询(media query)
媒体查询是css3的一个新增语法属性,它根据页面的视口宽度来定义特殊的 CSS 规则,一般用于进行移动端适配。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scala=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
<title>Title</title>
<link rel="stylesheet" media="screen and (min-width: 1500px)" href="body.css">
<style>
.box{
max-width: 100%;
width: 600px;
height: 200px;
background: blue;
color: #fff;
font-size: 16px;
}
@media screen and (max-width: 1000px ) {
.box{
background: yellow;
}
}
@media screen and (min-width: 1001px ) and (max-width: 1499px) {
.box{
background: red;
}
}
</style>
</head>
<body>
<div class="box">hello, world!!!</div>
</body>
</html>
开发准备
我们接下来开发的项目是魔方APP,主要通过APICloud+Flask完成。
注册APICloud帐号
APICloud官网:https://www.apicloud.com
开发文档:https://docs.apicloud.com
下载APP开发编辑器
注册成功,登录进入开发控制台,找到页面右下角点击开发工具跳转到工具下载页面。
Windows下载就行
网站地址:https://www.apicloud.com/devtools
下载完成以后,无需安装,直接解压,打开编辑器并登录APICloud。
接下来开发APP的时候,肯定是要查看代码运行后的效果,所以我们需要安装安卓模拟器,当然也可以使用真机调试.
推荐: 市面上大部分的模拟器都差不多,使用人数最多,一般都是: 海马玩模拟器, 夜神模拟器, 雷电模拟器.
我们这里安装和使用雷电模拟器.
如果使用mac os 开发的同学,安装夜神模拟器.
夜神的官网: https://www.yeshen.com/
安装完成以后:
我们调整下版面设置为移动端手机的. - 软件设置 - 手机版
下载APP开发调试工具
在前面登录的APICloud开发控制台中,找到页面右下角点击SDK下载跳转到工具下载页面。
网址:https://docs.apicloud.com/Download/download
点击AppLoader下载APP加载器工具,如扫码无法下载,则手动下载压缩包,通过USB连接电脑拖动到手机中进行安装。
可以在真实手机中安装AppLoader,
也可以在模拟器中安装AppLoader,
移动端项目搭建
在打开的APICloud编辑器中点选新建项目即可。
填写项目相关选项。
创建项目成功。
接下来,可以打开index.html页面,这是APP的欢迎页面。
模拟器调试
在模拟器中打开AppLoader, 显示效果如下:
注意看到屏幕右方有个白色的小圆按钮!点击这个按钮,可以设置和APICloud stodio编辑器进行代码同步, 进行调试APP运行的效果:
上面弹出的2个输入框,需要我们在代码编辑器APICloud Stodio中的左边窗口处右键点击项目名
此时代码编辑器APICloud Stodio窗口的右上角, 出现以下弹窗, 复制里面提供的IP和端口,其中IP一般才用第一个,但是部分网络下,可能第一个不行,则后面逐个填写.
点击连接以后,如果效果白色的小圆按钮变绿色,则表示配置连接成功.可以进行模拟器APP测试了.
此时可以在APICloud Stodio代码编辑器中通过鼠标右键点击项目目录,选择,WIFI同步,打开, 接着选择全量同步.
当然, 在开发中,使用模拟器是为了提高开发效率,但是模拟器毕竟不是真实设备,所以有时候,我们也需要使用和连接到真实设备中进行调试开发.
真机调试
通过APICloud开发工具,在真实设备下生成一个临时的APP,查看效果。这个步骤,我们叫真机调试。
首先,必须确保当前手机中已经安装了APPLoader工具.
鼠标右键点击左上角的项目目录,点选菜单中的USB同步(xxx)选项。[最好准备一条好的!注意是好的USB线.]
或者保证电脑和手机同一网段WiFi也可以向模拟器调试一样
APICloud 前端框架
APICloud内置了一个APICloud 前端框架给我们操作APP页面和展示数据,也提供了ajax跨域请求数据功能。
它本质上就是一个仿照jQuery编写的一个小工具库,所以并不好用。
框架地址:https://docs.apicloud.com/Front-end-Framework/framework-dev-guide
目录结构[只需了解]
APP/
|- index.html # 默认app配置的入口页面
|- config.xml # APP系统配置文件
|- html/ # APP页面存储目录
|- css/ # 样式目录
|- script/ # js脚本目录
|- image/ # 图片目录
配置文件
<widget id="A6177992056006" version="0.0.1">
<name>APP名称,展示给客户端手机里面的</name>
<description>
APP的描述信息,将来app上架以后,会需要填写
</description>
<author email="作者邮箱" href="官网地址">
APP作者名字
</author>
<!-- APP启动以后看到的首页,使用相对路径 -->
<content src="index.html" />
<!-- 设置APP的所有页面是否能跨域访问到本地或者远程服务器,*表示没有任何限制,local表示本地,如果是远程服务器,则需要编写完整的地址,例如:http://www.baidu.com/ -->
<access origin="*" />
<preference name="pageBounce" value="false"/>
<!-- APP背景颜色 -->
<preference name="appBackground" value="rgba(0,0,0,0.0)"/>
<!-- 配置Window默认背景 -->
<preference name="windowBackground" value="rgba(0,0,0,0.0)"/>
<!-- 配置Frame默认背景 -->
<preference name="frameBackgroundColor" value="rgba(0,0,0,0.0)"/>
<!-- 配置页面默认是否显示滚动条 -->
<preference name="hScrollBarEnabled" value="false"/>
<!-- 配置页面默认是否显示滚动条 -->
<preference name="vScrollBarEnabled" value="false"/>
<!-- 配置启动页是否自动隐藏 -->
<preference name="autoLaunch" value="true"/>
<!-- 配置应用是否全屏运行 -->
<preference name="fullScreen" value="false"/>
<!-- 配置应用是否自动检测更新 -->
<preference name="autoUpdate" value="true" />
<!--配置应用是否支持增量更新、云修复 -->
<preference name="smartUpdate" value="false" />
<!-- 配置应用开启/关闭调试模式 -->
<preference name="debug" value="true"/>
<!-- IOS全屏配置 -->
<preference name="statusBarAppearance" value="true"/>
<permission name="readPhoneState" />
<permission name="camera" />
<permission name="record" />
<permission name="location" />
<permission name="fileSystem" />
<permission name="internet" />
<permission name="bootCompleted" />
<permission name="hardware" />
</widget>
调用框架[只需了解]
<script src="./script/api.js"></script>
APICloud 前端框架中提供的40多个操作方法,主要分6类用途:
数据操作:
trim() trimAll() isArray() jsonToStr() strToJson() get()
post()
事件操作:
addEvt() rmEvt()
元素查找:
one() dom() domAll() byId() first() last() eq() not() prev() next() contains() closest()
DOM操作:
remove() attr() removeAttr() hasCls() addCls() removeCls() toggleCls() val() prepend() append() before() after()
html() text() offset() css() cssVal()
本地存储:
setStorage() getStorage() rmStorage() clearStorage()
系统兼容:
fixIos7Bar() fixStatusBar()
代码:
let ele = $api.byId("company");
console.log( ele );
let content = $api.html(ele);
console.log(content);
所有的APICloud前端框架的代码都必须在其入口函数中执行,并且通过$api
来进行调用。
api与$api对象
注意:在APICloud中存在2个全局对象,分别是$api和api对象。这两个对象是不同的。
$api必须是在api.js脚本文件引入以后才提供给开发者使用的。而 api 对象,则需要在入口函数才能使用的。
api对象主要是由APP系统提供给我们开发者操作和读取设备信息的。
而
$api
是APICloud模仿了jquery的$
对象提供给开发者用于操作app页面的对象。api对象的操作代码必须写在apiready入口函数中,否则报错!
而
$api
则不会报错,但是强烈建议不管是$api
还是api,只需要是js代码都写进入口函数中。
代码:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
<meta name="format-detection" content="telephone=no,email=no,date=no,address=no">
<title>磨坊 APP</title>
</head>
<body>
<div id="wrap">
<div id="header">
<h1>老男孩 python~~~</h1>
</div>
<div id="main" class="flex-con">
</div>
<div id="footer">
<h5>Copyright ©<span id="year"></span> </h5>
</div>
<div id="info">
</div>
</div>
</body>
<script type="text/javascript" src="./js/api.js"></script>
<script type="text/javascript">
apiready = function(){
var header = document.querySelector(‘#header‘);
$api.fixStatusBar(header);
var el = $api.byId("header");
var h1 = $api.first(el);
var content = $api.html(h1,"2020-08-27");
var ver = api.version;
var sType = api.systemType;
var sVer = api.systemVersion;
var id = api.deviceId;
var model = api.deviceModel;
var name = api.deviceName;
var cType = api.connectionType;
var winName = api.winName;
var winWidth = api.winWidth;
var winHeight = api.winHeight;
var frameName = api.frameName || ‘‘;
var frameWidth = api.frameWidth || ‘‘;
var frameHeight = api.frameHeight || ‘‘;
var str = ‘<ul>‘;
str += ‘<li>引擎版本信息: ‘ + ver + ‘</li>‘;
str += ‘<li>系统类型: ‘ + sType + ‘</li>‘;
str += ‘<li>系统版本: ‘ + sVer + ‘</li>‘;
str += ‘<li>设备标识: ‘ + id + ‘</li>‘;
str += ‘<li>设备型号: ‘ + model + ‘</li>‘;
str += ‘<li>设备名称: ‘ + name + ‘</li>‘;
str += ‘<li>网络状态: ‘ + cType + ‘</li>‘;
str += ‘<li>主窗口名字: ‘ + winName + ‘</li>‘;
str += ‘<li>主窗口宽度: ‘ + winWidth + ‘</li>‘;
str += ‘<li>主窗口高度: ‘ + winHeight + ‘</li>‘;
str += ‘<li>子窗口名字: ‘ + frameName + ‘</li>‘;
str += ‘<li>子窗口宽度: ‘ + frameWidth + ‘</li>‘;
str += ‘<li>子窗口高度: ‘ + frameHeight + ‘</li>‘;
str += ‘</ul>‘;
$api.html($api.byId("info"), str);
};
</script>
</html>
获取服务端API接口
API,译作:应用程序接口,实际上就是应用程序对外暴露到第三方进行数据数据/状态变更的地址/方法
获取数据可以使用$api.post()
,当然,也可以使用api对象
提供的api.ajax
。
api.ajax[只需了解]
基本语法:
api.ajax({
url: ‘API接口地址‘, // 必须加上协议
method: ‘请求方法‘, // post、get、put、delete
dataType: "json", // 服务端数据响应格式
cache: true, // 缓存数据,若缓存,下次没网络时请求则会使用缓存,
// 仅在get请求有效
timeout: 30, // 超时时间,单位:秒
headers:{}, // 请求头,里面的key使用首字母大写的形式,
// 如 Content-Type
report:false, // 是否实时返回上传文件的进度,只有上传时使用
data: { // 提交数据
values: { // 以表单格式提交数据
name: ‘haha‘
},
body: "", // 以字符串格式提交数据,body和values是冲突的,只能使用其中一个
files: { // ajax上传文件
file: ‘fs://a.gif‘ // 文件字段名
}
}
},function(ret, err){ // 回调函数,参数1是响应内容,参数2是错误信息
if (ret) {
alert( JSON.stringify( ret ) );
} else {
alert( JSON.stringify( err ) );
}
});
接下来的开发中,我们需要实现客户端,所以如果基于上面的$api开发的话,非常的影响效率,所以我们可以采用Vue.js来完成app的客户端开发.当然最终代码还是运行在APICloud里面.
vue+axios
vue.js:https://vuejs.org/js/vue.js
axios.js:https://www.npmjs.com/package/axios
把下载回来的vue.js和axios.js保存到项目的static/目录下,然后在主页面中引入。
<script src="..//vue.js"></script>
<script src="../script/axios.js"></script>
<script src="../script/main.js"></script>
构建前端项目目录
APP/
|- config.xml # APP系统配置文件
|- html/ # APP页面存储目录
| |- index.html # 项目主页面
|- static/ # 静态资源目录
|- js/ # js脚本目录
| |- vue.js
| |- axios.js
| |- main.js # js的入口程序,项目的主要工具库,公共代码保存文件
|- css/
|- images/
config.xml,代码:
<content src="html/index.html" />
html/index.html,代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="format-detection" content="telephone=no, email=no, date=no, address=no">
<title>魔方APP</title>
<script src="../static/js/vue.js"></script>
<script src="../static/js/axios.js"></script>
<script src="../static/js/main.js"></script>
</head>
<body>
<h1>魔方</h1>
</body>
</html>