安卓开发

android 混合开发,android混合开发

混合开发的App(Hybrid App)就是在一个App中内嵌一个轻量级的浏览器,一部分原生的功能改为Html 5来开发,这部分功能不仅能够在不升级App的情况下动态更新,而且可以在Android或iOS的App上同时运行,让用户的体验更好又可以节省开发的资源。

Hybrid开发中关键问题是什么想要在一个App中显示一个Html 5网页的功能,其实很简单,只要一个WebView就可以了。你可以点击链接来跳转网页。像这样的功能就能叫做Hybrid 开发了嘛?显然不是的。

我觉得一个Hybrid开发的App中必须要要有的功能就是Html 5页面和Native App怎么进行交互。比如,我点了一个Html 5页面上的一个按钮或链接,我能不能够跳转到Native App的某个页面;比如我点了Html 5页面上的分享按钮,我能不能调用Native App的分享功能;比如Html加载的时候能不能获取Native App的用户信息等等。

Html 5和Native的交互WebView 本来就支持js和Java相互调用,你只需要开启 WebView 的JavaScript脚本执行,然后通过代码mWebView.addJavascriptInterface(new JsBridge(), “bxbxbai”); 向Html 5页面时注入一个Java对象,然后就可以在Html 5页面中调用Native的功能了

微信怎么做的微信应该是Hybrid 开发做的最好的App之一,它是怎么做交互的呢?

答案就是 微信JS-SDK ,去微信开发者文档中可以看到,微信JS-SDK封装了各种微信的功能,比如分享到朋友圈,图像接口,音频接口,支付接口地理位置接口等等。开发者只需要调用微信JS-SDK中的函数,然后统一由JS-SDK来调用微信中的功能,这样好处就是我写了一个Html 5的应用或网页,在Android和iOS的微信中都可以正常运行了

然后在我自己的App中加载这个Html 5页面就可以看到下图, @小比比说 这样的文字是可以点击跳转到个人,点击播放按钮是可以播放音乐的

从Html源代码中可以看到如下信息:

反编译代码后,在云音乐的代码中找到了 this.mWebView.setWebViewClient(new cf(this)); 这么一句代码,进入 cf 类,发现下面代码:

public boolean shouldOverrideUrlLoading(WebView webView, String url) {

if (url.startsWith(“orpheus://”)) {

RedirectActivity.a(this.activity, url);

return true;

return false;

this.activity.startActivity(new Intent(“android.intent.action.VIEW”, Uri.parse(url)));

return true;

} catch (ActivityNotFoundException localActivityNotFoundException) {

localActivityNotFoundException.printStackTrace();

return true;

果然如此,再进入 RedirectActivity ,这是一个没有任何界面的Activity,专门用于处理页面跳转信息,它会调用一个方法NeteaseMusicUtils.redirect(this, getIntent().getData().toString(), false) 来处理url, redirect 方法的名字是我自己写的,部分代码如下:

然后我自己写了代码拦截Html 5的跳转,打印出的Log如下:

总结一般来讲,也是我目前知道的两种主流的方式就是

js调用Native中的代码Schema:WebView拦截页面跳转第2种方式实现起来很简单,但是一个致命的问题就是这种交互方式是单向的,Html 5无法实现回调。像云音乐App中这种点击跳转到具体页面的功能,Schema的方式确实可以简单实现,而且也非常适合。如果需求变得复杂,假如Html 5需要获取Native App中的用户信息,那么最好使用js调用的方式。

js和Native进行交互上面讲到WebViewbe本身就是支持js调用Native代码的,不过WebView的这个功能在Android 4.2(API 17)一下存在高危的漏洞。这个漏洞的原理就是Android系统通过 WebView.addJavascriptInterface(Object o, String interface) 方法注册可供js调用的Java对象,但是系统并没有对注册的Java对象方法调用做限制。导致攻击者可以利用反射调用未注册的其他任何Java对象,攻击者可以根据客户端的能力做任何事情。 这篇文章详细的介绍了这个漏洞

出于安全考虑,Android 4.2以后的系统规定允许被js调用的Java方法必须以 @JavascriptInterface 进行注解

Cordova的解决方案Cordova是一个广泛使用的Hybrid开发框架,它提供了一套js和Native交互规范

在Cordova的 SystemWebViewEngine 类中可以看到

private static void exposeJsInterface(WebView webView, CordovaBridge bridge) {

if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)) {

Log.i(TAG, “Disabled addJavascriptInterface() bridge since Android version is old.”);

// Bug being that Java Strings do not get converted to JS strings automatically.

// This isn’t hard to work-around on the JS side, but it’s easier to just

// use the prompt bridge instead.

webView.addJavascriptInterface(new SystemExposedJsApi(bridge), “_cordovaNative”);

因此当Android系统高于4.2时,Cordova还是使用 addJavascriptInterface 这种方式,因为这个方法在高版本上安全而且简单,低于4.2的时候,用什么方法呢?

答案是 WebChromeClient.onJsPrompt 方法

WebView可以设置一个 WebChromeClient 对象,它可以处理js的3个方法

onJsAlertonJsConfirmonJsPrompt这3个方法分别对应js的 alert 、 confirm 、 prompt 方法,因为只有 prompt 接收返回值,所以js调用一个Native方法后可以等待Native返回一个参数。下面是 cordova.js 中的一段代码:

Similar Posts

发表评论

邮箱地址不会被公开。 必填项已用*标注