开发Hybrid App的技术选型
一、前言
如果我们把Hybrid App理解为运行在android或者ios以及其他移动终端设备上的应用,也可以叫做H5 APP,这种开发应用的模式结合web开发技术与Native开发的部分技术,通常也被称为混合开发模式。
二、移动应用开发的三种方式
- Native App:原生应用,在android端通常使用Java或Kotlin开发,ios端使用OC或者Swift开发
- Hybrid App:混合应用,结合Web与Native技术开发
- Web App:web应用,网页三剑客html+css+js
Native App开发依旧是移动应用的主导,但如今的Native App或多或少会嵌入一些web页面,诸如淘宝、京东等APP,所以如今真正意义上的原生应用又该如何去定义呢?Hybrid App受到越来越多开发者的追捧与其开发周期短,开发难度小,跨平台离不开,当然APP的效果也成为大家诟病的话题,如首屏打开缓慢,动画效果不够流畅等。
三种方式的技术比较(图片来自网络)
三、Hybrid App开发的核心
毫无疑问,webview是Hybrid App开发的核心。webview可以简单的理解为一个浏览器。webview 使用的是手机自带的浏览器内核,一般来说,手机厂家在内置浏览器的时候都会对其内核做一定的修改,所以在webview渲染的内容可能或有些差异,但是这基本上不影响APP的开发。绝大部分手机都使用的是WebKit作为webview的渲染引擎。关于WebKit以及其他的浏览器内核知识可以查看这里。
关于webview的知识点非常多,如在android上常用的属性:WebSettings、WebViewClient,与JavaScript的交互,js注入漏洞,jsBridge等等,在此以Kotlin为例实现一个简单的例子,项目源码点击这里。
MAinActivity.kt
package com.example.wxqdoit.kotlintest
import android.os.Build
import android.os.Bundle
import android.support.annotation.RequiresApi
import android.support.design.widget.BottomNavigationView
import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {@RequiresApi(Build.VERSION_CODES.O)override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)bottom_navigation.setOnNavigationItemSelectedListener(mBottomNavigationView)val fragments: MutableList<Fragment> = ArrayList<Fragment>()fragments.add(Fragment1("https://www.baidu.com"))fragments.add(Fragment1("https://www.jianshu.com"))fragments.add(Fragment1("https://aidn.jp/mikutap/"))vp_main.adapter = ViewPagerAdapter(supportFragmentManager,fragments)}private val mBottomNavigationView = BottomNavigationView.OnNavigationItemSelectedListener { item ->when (item.itemId) {R.id.word -> {//vp_main.currentItem = 0Toast.makeText(this,"点击了",Toast.LENGTH_SHORT).show()return@OnNavigationItemSelectedListener true}R.id.pic -> {//vp_main.currentItem = 1return@OnNavigationItemSelectedListener true}R.id.me -> {//vp_main.currentItem = 2return@OnNavigationItemSelectedListener true}}false}
}
ViewPagerAdapter.kt
package com.example.wxqdoit.kotlintest
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentPagerAdapter
//继承 FragmentPagerAdapter 创建适配器
class ViewPagerAdapter(fm: FragmentManager?, var list: List<Fragment>) : FragmentPagerAdapter(fm) {override fun getItem(position: Int): Fragment {return list.get(position)}override fun getCount(): Int {return list.size}
}
Fragment1.kt
package com.example.wxqdoit.kotlintest
import android.annotation.SuppressLint
import android.os.Build
import android.os.Bundle
import android.support.annotation.RequiresApi
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import kotlinx.android.synthetic.main.fragment1.view.*
@SuppressLint("ValidFragment")
class Fragment1(private val url: String):Fragment() {@SuppressLint("SetJavaScriptEnabled")@RequiresApi(Build.VERSION_CODES.O)override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {val view = inflater.inflate(R.layout.fragment1, container, false)val webView = view.testWebViewwebView!!.webViewClient = webClientwebView.settings.javaScriptEnabled = truewebView.settings.allowContentAccess = truewebView.settings.layoutAlgorithmwebView.loadUrl(url)return view}private val webClient = object : WebViewClient() {@RequiresApi(Build.VERSION_CODES.LOLLIPOP)override fun shouldOverrideUrlLoading(view: WebView, request:WebResourceRequest ): Boolean {view.loadUrl(request.url.toString())return true}}
}
效果如下
四、移动APP适配
做过原生开发的都知道美术需要出几套图以适配不同的分辨率,720×1280、750×1334、1080×1920、1242×2208,更大或者更小的屏在市面上也常见,android上字体大小通常以dp、sp作为单位。Hybrid App在只有一套美术UI的情况下应当如何处理以适配不同的机型呢?
媒体查询、百分比,或是直接使用web端常用的单位px、em、rem以及vh、vw,都是常用的适配方案。在设计稿给到固定宽度的情况下,相对而言,使用rem作为单位是比较合理的选择,至于移动设备适配,屏幕宽度,逻辑像素、物理像素、dpi等知识就不在此处赘述,分享优秀的博客:
移动设备适配基础知识速成:weibo.com/p/1001603933391216084991
五、flexible.js
flexible是淘宝使用的移动端适配方案,原理即根据机型分辨率进行适配,设置根font-size,使用相对单位rem。其核心功能如下:
- 判断meta标签,动态改写标签
- 给html标签添加data-dpr属性
- 给html标签添加font-size属性
根font-size(即html标签上的)属性值即为一个单位的rem,在chrome浏览器上,默认的font-size值为16px:即16px=1rem
getComputedStyle(document.getElementsByTagName("html")[0])["font-size"];
//16px
flexible.js核心代码:
function refreshRem(){var width = docEl.getBoundingClientRect().width;if (width / dpr > 540) {width = 540 * dpr;}var rem = width / 10;docEl.style.fontSize = rem + 'px';docEl.setAttribute("font-size",rem + 'px');flexible.rem = win.rem = rem;}win.addEventListener('resize', function() {clearTimeout(tid);tid = setTimeout(refreshRem, 200);}, false);win.addEventListener('pageshow', function(e) {if (e.persisted) {clearTimeout(tid);tid = setTimeout(refreshRem, 200);}}, false);
将设备宽度分为10份,而每一份视作一个单位,再将html的font-size设置为这个单位即:
font-size = 750/10 = 75px;
1rem = 75px;
如果在宽度为750px的设备上,完全符合上述换算。如果在iphone6/7/8上,宽度为375,那么:
font-size = 375/10 = 37.5px;
1rem = 37.5px;
现在以宽为750的设计稿为例,有一个款750px高75px的按钮 ;在iphone6/7/8上(实际宽375px)我们实际看到的宽高是多少呢?
width = 750/75 = 10rem ---> 10rem(在iphone6/7/8上) = 37.5px*10 = 375px;
height = 75/75 = 1rem --->1rem(在iphone6/7/8上) = 37.5px;
不难看出,只需要将这个单位作为除数即可计算出所需要的值;
六、打包工具
开发完成之后使用hbuilder或cordova打包成为android APK或者ios IPA。我更偏向于cordova,插件相对更多,社区更加活跃,稳定的更新维护。当然,孰优孰劣各自体会。下文会具体介绍cordova的相关知识。
Hbuild:http://www.dcloud.io/
cordova:https://cordova.apache.org/
七、UI框架
开发框架常用的有ionic,mui,jQuery Mobile,weui等等。就事实而论,当设计稿给到开发者时,或者这些都用不到,全套UI自己写也是常见的。
八、angular、react还是vue?
angular、react相对而言比较重,vue显得轻量一些,当开发大型SPA应用时,前两者是不错的选择,而vue完整的工具链以及活跃的社区也适应绝大部分的开发场景。
九、jQuery还用吗?
对于事件的封装,DOM操作的实现都是毫无疑问需要使用的,同时集成的ajax封装也必不可少,不过不论是Web APP的开发还是 Hybrid App的开发,jq都是不二之选。但当我们在对请求过滤的处理时,这些get,post方法基本上不能满足我们的需求,所以需要对请求进行二次封装。
/*** 通用请求数据接口* @param reqUrl* @param reqType* @param data* @param fn*/commonRequest: function commonRequest(reqUrl, reqType, data, fn) {$.ajax({url: reqUrl,type: reqType,data: data,async: false,success: function success(data) {fn(data);},error: function error(data) {$.lightTip.error("网络请求错误-" + data.status, 2000);}});},/*** 二次封装get请求* @param reqUrl* @param data* @param fn*/get: function get(reqUrl, data, fn) {$.ajax({url: reqUrl,type: 'GET',data: data,async: false,success: function success(data) {if (data.meta.code === 200) {fn(data);} else {alert(data.meta.message);throw new Error(data.meta.message);}},error: function error(data) {$.lightTip.error("网络请求错误-" + data.status, 2000);}});},/*** 二次封装post请求* @param reqUrl* @param data* @param fn*/post: function post(reqUrl, data, fn) {$.ajax({url: reqUrl,type: 'POST',data: data,async: false,success: function success(data) {if (data.meta.code === 200) {fn(data);} else {alert(data.meta.message);throw new Error(data.meta.message);}},error: function error(data) {$.lightTip.error("网络请求错误-" + data.status, 2000);}});},/*** formData上传数据* @param reqUrl* @param reqType* @param data* @param fn*/formDataReq: function formDataReq(reqUrl, reqType, data, fn) {$.ajax({url: reqUrl,data: data,type: reqType,processData: false,contentType: false,success: function success(data) {if (data.meta.code === 200) {fn(data);} else {alert(data.meta.message);throw new Error(data.meta.message);}},error: function error(data) {$.lightTip.error("网络请求错误-" + data.status, 2000);}});},
这样封装一次,当用户没有登录时,可以根据返回的数据进行过滤处理。
当然如果你不用jq也可以选择其他的类库如封装ajax请求的axios!
十、swiper是个好东西
swiper常用于移动端网站的内容触摸滑动,是纯javascript打造的滑动特效插件,面向手机、平板电脑等移动终端,Swiper能实现触屏焦点图、触屏Tab切换、触屏多图切换等常用效。这个插件功能确实强大,官网惊艳,api文档走心,性能不错。用作APP开发的主容器亦有一战之力。
十一、cordova开发详解
1、cordova开发环境搭建,以android为例
1、安装jdk(建议jdk8+),配置环境变量;
2、安装android sdk(至少到27,也可以安装android studio依赖安装),配置环境变量;
3、安装node(npm,也可以选择使用yarn)(node建议8+),如果不是默认安装,请配置环境变量;
4、安装bower,用以下载各种前端类库;
5、使用npm install -g cordova全局安装cordova,如果安装过慢或失败请科学上网;
2、创建一个app并运行起来
1、cordova create [文件夹名] [包名] [app名]
$ cordova create hello com.example.hello HelloWorld
2、添加平台(以android为例)
$ cd hello$ cordova platform add android
3、build项目
cordova build android
......
.....
...
.
BUILD SUCCESSFUL in 7s
47 actionable tasks: 1 executed, 46 up-to-date
Built the following apk(s):D:\dev\****\****\****\platforms\android\app\build\outputs\apk\debug\app-debug.apk
在路径:\platforms\android\app\build\outputs\apk\debug\app-debug.apk下可以找到apk文件。
3、常用命令
Global Commandscreate ............................. 创建项目help ............................... 获取帮助telemetry .......................... 开启或关闭遥测采集config ............................. 全局配置
Project Commandsinfo ............................... 项目基本信息requirements ....................... 检查并打印出指定平台的所有要求platform ........................... 管理项目平台plugin ............................. 管理插件compile ............................ 编译项目clean .............................. 清除项目
更多命令可以到官网查看。
4、项目结构
如果项目成功运行,您看到的项目结构应该如下:
www文件夹作为开发主文件夹;
res文件夹存放app的闪屏图片和icon;
plugins文件夹存放插件;
plaatforms文件夹存放诸如android、ios等各端的文件;
node-modules文件夹自然是依赖的各个模块
config.xml是项目的配置文件,你添加的插件将会在里面显示,如状态栏插件,你可以添加更多插件。
<plugin name="cordova-plugin-statusbar" spec="^2.4.2" />
5、常用插件收集:
phonegap-plugin-barcodescanner : 二维码扫描
cordova-plugin-statusbar:状态栏
cordova-plugin-inappbrowser: 内置浏览
cordova-plugin-camera:照相机
插件太多可查看这里
官方的插件搜索地址点击这里
6、插件使用,以imagePicker为例子
cordova plugin add cordova-plugin-imagepicker
使用:
document.addEventListener("deviceready",onDeviceReady);function onDeviceReady(){console.log("onDeviceReady");$(document).on("tap","#getPictures",()=>{window.imagePicker.getPictures(function(results) {for (let i = 0; i < results.length; i++) {console.log('Image URI: ' + results[i]);alert('Image URI: ' + results[i]);}}, function (error) {console.log('Error: ' + error);alert('Error: ' + error);},{maxImages: 9,width: 500,height: 500,quality:60});})}
当然要实现QQ登录、微信登录等功能也是完全没有问题的,只需要添加对应的插件使用就可以了。
7、构建release版本以及签名
构建release版本
cordova build android --release
对 APK 签名
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore release-key.keystore platforms/android/build/outputs/apk/android-release-unsigned.apk [秘钥]apk签名的相关知识比较复杂,可以阅读这一篇:Cordova 打包 Android release app 过程详解
转载于:https://my.oschina.net/wxqdoit/blog/2992525
开发Hybrid App的技术选型相关推荐
- 移动App开发、App和Web区别、开发移动app时技术选型
移动App开发 混合移动App: 移动端App开发有Android和iOS及混合App,开发它们采用不同的语言,如: 苹果软件使用: OC.或者Swift语言开发. 安卓软件使用:Java,安卓控件进 ...
- 移动IM开发那些事:技术选型和常见问题
最近在做一个iOS IM SDK,在内部试用的阶段,不断有兄弟部门或者合作伙伴过来问各种技术细节,所以统一写一篇文章记录,统一介绍下一个IM APP的方方面面,包括技术选型(包括通讯方式,网络连接方式 ...
- 混合开发Hybrid App为何成为热门?
纵观当前的移动开发,混合开发(Hybird App)的热度日益上升,那么导致这一趋势的是何原因呢? 实际上,除了混合开发,移动端的开发方式还有纯原生(Native App)和网页应用(Web App) ...
- 混合开发Hybrid App有哪些优势和不足?
从当前移动开发的实际情况来看,移动端的开发方式三分天下:纯原生(Native App).混合开发(Hybird App).网页应用(Web App). 纯原生(Native App):是在 Andro ...
- 混合 APP 开发(Hybrid App)
目录 混合 App Html5简介 UIWebView 和 WKWebView UIWebView 和 JS 交互 WKWebView 和 JS 交互 JS 调用 Native 相机 一. 混合 AP ...
- Java开发中Websocket的技术选型参考
1. 前言 Websocket是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议.WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据 ...
- 关于使用AIR开发移动APP 的技术解决方案 笔记
最近在使用AIR开发跨平台APP的时候遇到了几大问题,再次一一提出技术方案和笔记 1.AIR 地图 选用google 抑或 百度 google已弃用flash api 百度每天只能请求2W次 ...
- 《江湖X》开发那些事 - 2.技术选型
写在开头,对于任何非尖端型研发项目的技术选型,我的忠告: 不要造次 江湖X技术选型 客户端: Unity(C#+lua) 服务器: SCut(C#) 数据库: redis.mysql 关于客户端游戏引 ...
- ionic+angularjs开发hybrid App(环境配置+创建测试项目)
本文使用的系统是win10 因为后期需要使用nodejs 所以先把node装好 https://nodejs.org/download/ 下载JDK并配置Java运行环境 http://www.ora ...
最新文章
- 涉密文件检查工具_肇庆高要销毁资料文件公司粉碎销毁文件资料公司欢迎您
- 《精通Unix下C语言与项目实践》读书笔记(16)
- java linux urlencode_java字符编码转换研究(转)
- Just a Simple Problem
- 使用 soapUI 测试 REST 服务
- Struts2学习笔记1
- 虚方法的使用 c# 1613719803
- for mew歌词 shell_求shell for mew的中文歌词
- 使用Python写入docx文件并控制字体颜色
- [转载] Python3.X之——卷积计算
- 刚刚用上Ubuntu18,Ubuntu20已经出来了
- mysql中整理设置__MySQL的常用操作命令整理
- 第三章 软件项目范围管理
- 英语在线听力翻译器_英语听力翻译器在线翻译PC版-英语听力翻译电脑版下载 v2.1.4--PC6电脑版...
- 衡量计算机主机性能的指标,计算机性能
- 在固定宽高内显示固定数量的最大正方形
- 计算机视觉最新研究方向,计算机视觉的主要研究的内容是什么?,计算机视觉研究方向...
- c语言等级分制度的作用,使用C语言怎么对学生的成绩等级进行划分
- 访问Daytime服务的客户端(TCP)
- 报表引擎终于做出来了!!!
热门文章
- 联想y410p预装win8,再用u盘安装ubuntu
- 纹身墨水行业调研报告 - 市场现状分析与发展前景预测
- 95后自述,00后都这么卷了吗?
- vue2 在线预览pdf文件
- 关于ad hoc retrieval的解释
- qmake *.prf文件 自定义features
- deepfakes怎么用_[mcj]deepfakesApp使用说明(3)
- 英文翻译-选择中国汽车工业的发展模式(含中英文)
- TP5100(2A开关降压 8.4V/4.2V锂电池 充电器芯片)
- GIS如何实现自动编号