[Android] [Hybrid APP开发简述]
Hybrid APP
Hybrid App(混合模式移动应用)是指介于web-app、native-app这两者之间的app,兼具“Native App良好用户交互体验的优势”和“Web App跨平台开发的优势”。
Hybrid App同时使用网页语言与程序语言开发,通过应用商店区分移动操作系统分发,用户需要安装使用的移动应用”。总体特性更接近Native App但是和Web App区别较大。只是因为同时使用了网页语言编码,所以开发成本和难度比Native App要小很多。因此说,Hybrid App兼具了Native App的所有优势,也兼具了Web App使用HTML5跨平台开发低成本的优势
Hybrid APP开发的分类
Hybrid App按网页语言与程序语言的混合,通常分为三种类型:多View混合型,单View混合型,Web主体型。
多View混合型
即Native View和Web View独立展示,交替出现。2012年常见的Hybrid App是Native View与WebView交替的场景出现。这种应用混合逻辑相对简单。即在需要的时候,将WebView当成一个独立的View(Activity)运行起来,在WebView内完成相关的展示操作。这种移动应用主体通常是Native App,Web技术只是起到补充作用。开发难度和Native App基本相当。
单View混合型
即在同一个View内,同时包括Native View和Web View。互相之间是覆盖(层叠)的关系。这种Hybrid App的开发成本较高,开发难度较大,但是体验较好。如百度搜索为代表的单View混合型移动应用,既可以实现充分的灵活性,又能实现较好的用户体验。
Web主体型
即移动应用的主体是Web View,主要以网页语言编写,穿插Native功能的Hybrid App开发类型。这种类型开发的移动应用体验相对而言存在缺陷,但整体开发难度大幅降低,并且基本可以实现跨平台。Web主体型的移动应用用户体验的好坏,主要取决于底层中间件的交互与跨平台的能力。国外的appMobi、PhoneGap和国内的WeX5、AppCan和Rexsee都属于Web主体型移动应用中间件。其中Rexsee不支持跨平台开发。appMobi和PhoneGap除基础的底层能力更多是通过插件(Plugins)扩展的机制实现Hybrid。AppCan除了插件机制,还提供了大量的单View混合型的接口来完善和弥补Web主体型Hybrid App体验差的问题,接近Native App的体验。而WeX5则在揉合PhoneGap和Bootstrap等主流技术的基础上,对性能进一步做了深度优化,不但完全具备Native App对本地资源的调用能力,性能体验也不输原生;WeX5所开发出来的app具备完全的跨端运行能力,可以无需任何修改直接运行在各种前端环境上。
从分析可见,Hybrid App中的Web主体型只要能够解决用户体验差的问题,就可以变成最佳Hybrid App解决方案类型。
hybrid app开发工具
1、AppCan
AppCan是国内Hybrid App混合模式开发的倡导者,AppCan应用引擎支持Hybrid App的开发和运行。并且着重解决了基于HTML5的移动应用”不流畅”和”体验差”的问题。使用AppCan应用引擎提供的Native交互能力,可以让HTML5开发的移动应用基本接近Native App的体验。[3]
AppCan作为中国Hybrid混合应用开发、移动平台、移动云平台的倡导者和领导者,以“免费+开源+开放”的互联网模式,为广大开发者提供一站式的移动应用开发支持服务。[4] 与此同时,从移动应用开发、管理、运营、安全四个方面,为各级政府和企事业单位,构建运营一体化的企业移动平台,企业通过个性化的移动运营门户,增强客户服务品质,提升整体经营管理水平。
现在,正益移动AppCan行业解决方案已成功应用于金融、航空、政府、石化、传媒等领域,客户包括东方航空、国家电网、中化集团、泰康人寿、新华社等众多大型企业,赢得了市场广泛认可,是国内企业移动信息化领域的龙头企业。
Hybrid开发效率高、跨平台、低层本
Hybrid从业务开发上讲,没有版本问题,有BUG能及时修复
移动应用开发的三种方式比较
移动应用开发的方式,目前主要有三种:
Native App: 本地应用程序(原生App)
Web App:网页应用程序(移动web)
Hybrid App:混合应用程序(混合App)
图1:三种移动应用开发方式
如图1所示,三种移动应用开发方式具体比较如表2所示:
表2:三种移动应用开发方式比较
混合开发应用场景
(1)折中考虑——如果企业使用 Hybrid 开发方法,就能集Native 和web两者之所长。一方面,Native 让开发者可以充分利用现代移动设备所提供的全部不同的特性和功能。另一方面,使用 Web 语言编写的所有代码都可以在不同的移动平台之间共享,使得开发和日常维护过程变得集中式、更简短、更经济高效。
(2)内部技能——许多企业都拥有Web 开发技能。如果选择 Hybrid 开发方法,在合适解决方案的支持下,Web 开发者只要仅仅运用 HTML、CSS 和 JavaScript 等 Web 技能,就能构建 App,同时提供 Native 用户体验。
(3)考虑未来——HTML5的可用性和功能都在迅速改进。许多分析师预测,它可能会成为开发前端 App 的默认技术。如果用 HTML 来编写 App 的大部分代码,并且只有在需要时才使用 Native 代码,公司就能确保他们今天的投入在明天不会变得过时,因为 HTML 功能变得更丰富,可以满足现代企业一系列更广泛的移动要求。
混合开发框架和层次结构图
混合开发结构图
1)移动终端web壳(以下简称“壳”):壳是使用操作系统的 API 来创建嵌入式 HTML的渲染引擎。壳主要功能是定义Android应用程序与网页之间的接口,允许网页中的JavaScript调用Android应用程序,提供基于web的应用程序的Android API,将Web嵌入到Android应用程序中。
2)前端交互js:包括基础功能js和业务功能js。
3)前端适配器:适配不同的终端:Pad、android、ios、wap。
Android中如何实现Bybird开发
其实在Android开发中使用hybrid模式开发app,也是有两种方案的:
使用第三方hybrid框架
自己使用webview加载
自主hybrid开发简单实现
在AndroidManifest.xml中定义网络请求权限
<uses-permission Android:name="Android.permission.INTERNET"/>
在Layout布局文件中定义Webview控件
<WebView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:id="@+id/webView"
/>
在代码中获取Webview控件加载本地或者网络H5资源
加载本地H5页面
/**
* 加载本地H5资源文件
*/
webView = (WebView) findViewById(R.id.webView);
webView.loadUrl("file:///Android_asset/example.html");
/**
* 加载网络H5资源
*/
webView = (WebView) findViewById(R.id.webView);
webView.loadUrl("http://baidu.com");
为Webview控件设置参数
WebSettings webSettings = h5Fragment.mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setAllowFileAccess(false);
webSettings.setUseWideViewPort(false);
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
webSettings.setDatabaseEnabled(false);
webSettings.setAppCacheEnabled(false);
webSettings.setBlockNetworkImage(true);
这里的WebSettings就是webview的设置参数对象,我们是通过它为webview设置各种参数值的,见名知意,看见名字我们就知道各个set方法的意思了。比如设置webview中的html页面js代码是否可用,是否可以访问系统文件,H5缓存是否可用,是否立即加载网页图片等等。
为Webview控件设置WebChromeClient
WebChromeClient对象是webview的关于页面效果回调方法的实现对象,主要用于实现webview页面上一些效果的回调,我们可以看一下其中实现的一些回调方法:
/**
* 自定义实现WebChromeClient对象
*/
public class MWebChromeClient extends WebChromeClient{
/**
* 当webview加载进度变化时回调该方法
*/
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
}
/**
* 当加载到H5页面title的时候回调该方法
*/
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
}
/**
* 当接收到icon的时候回调该方法
*/
@Override
public void onReceivedIcon(WebView view, Bitmap icon) {
super.onReceivedIcon(view, icon);
}
/**
* 当H5页面调用js的Alert方法的时候回调该方法
*/
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
return super.onJsAlert(view, url, message, result);
}
/**
* 当H5页面调用js的Confirm方法的时候回调该方法
*/
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
return super.onJsConfirm(view, url, message, result);
}
/**
* 当H5页面调用js的Prompt方法的时候回调该方法
*/
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
return super.onJsPrompt(view, url, message, defaultValue, result);
}
}
上面的WebChromeClient中我们重写了其中的几个字方法,我们已经在方法中添加了注释标明了各个方法的调用时机,而且通过方法名我们也不难发现各个方法的具体作用,这里就不在具体的介绍了。
为Webview主要设置WebviewClient
/** * 自定义实现WebViewClient类 */ public class MWebViewClient extends WebViewClient {
/**
* 在webview加载URL的时候可以截获这个动作, 这里主要说它的返回值的问题:
* 1、返回: return true; webview处理url是根据程序来执行的。
* 2、返回: return false; webview处理url是在webview内部执行。
*/
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
}
/**
* 在webview开始加载页面的时候回调该方法
*/
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
/**
* 在webview加载页面结束的时候回调该方法
*/
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
/**
* 加载页面失败的时候回调该方法
*/
// 该方法为Android23中新添加的API,Android23中会执行该方法
@TargetApi(21)
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
}
/**
* 加载页面失败的时候回调该方法
*/
/**
* 在Android23中改方法被onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) 替代
* 因此在Android23中执行替代方法
* 在Android23之前执行该方法
* @param view
* @param errorCode
* @param description
* @param failingUrl
*/
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
} }