混合开发:Android的WebView加载H5,和H5的互调|SquirrelNote

前言

混合开发,不仅仅显示一个WebView,有时还需要本地Java代码与HTML中的JavaScript进行交互,Android也对交互进行了很好的封装。例如:点击网页中的按钮,调用Android中的原生对话框;点击网页中的电话号码,调用Android中的拨号APP。

  1. 为什么要学习与H5互调
  2. Hybrid混合开发(原生/H5)
  3. Hybrid混合开发应用场景
  4. WebView如何加载H5页面
  5. Android如何调用H5中的方法
  6. H5如何调用Android中的方法

为什么要学习与H5互调

目前,微信、QQ空间等大量软件都内嵌了H5。Android与H5互调可以让我们实现混合开发。混合开发就是在一个APP中内嵌一个轻量级的浏览器,一部分原生的功能改为Html5来开发。

原理:就是Java代码和JavaScript之间的调用。

Hybrid混合开发(原生/H5)

在项目中,从需求来说,大部分页面用H5实现,可以减少很多工作量。但因为不可控因素太高,而时间又短,风险太大。而我们对原生比较熟,开发效率比较高,很多东西控制得了,风险相对较低。并且主推产品是App,微信属于辅助性产品。所以以原生为主,H5为辅,App大部分页面用原生完成,小部分用WebView加载H5。

如果人员和时间资源充足的话,我会以H5为主,微信和App都有的页面,统一用H5。App专有的部分,比如导航栏、标题栏、登录等,用原生实现。另外,WebView里的H5有点击事件时,也许是URL链接,也许是调用JS的,都不会让它直接在该WebView里做跳转,需要拦截下来做原生处理,然后再跳转到一个新的原生界面,原生页面可以嵌入另一个WebView,用来展示新的H5页面。

下面谈下混合开发具体的应用场景:

Hybrid混合开发应用场景

一些基础的功能,比如调用手机的摄像头,获取地理位置,登录注册功能等等,做成Native的功能,让Html5来调用。

如果把一个登录和注册功能也做成Html5,在弱网络环境下,可能会等半天还没加载出页面。所以使用Native开发会快一些。
那么什么情况适合使用Html5来开发呢?像一些活动页面,比如秒杀、团购等适合做Html5,因为这些页面可能设计的非常炫而且复杂,Html5开发会简单点。并且这些页面时效性短,更新更快,因为一个活动说不定就一周时间,下周换活动,如果这样的话,做成Native是肯定不行的。

WebView如何加载H5页面

Android是通过WebView来加载Html页面的,WebView加载H5有两种模式,一种是加载服务器的H5页面,一种是加载本地的H5页面。加载服务器的H5页面比较简单,只要load一下URL就可以了。加载本地的H5页面,需要将H5页面存放在本地,包括关联的CSS和JS文件,这种方式相对比较复杂,但是加载速度会比第一种快很多。
根据Html文件所在的位置不同,写法也不同:


image.png
//方式一:加载assets文件夹下的test.html页面
mWebView.loadUrl("file:///android_asset/files/js_java_interaction.html");
//方式二:加载网页
//mWebView.loadUrl("http://www.baidu.com");

实现java和js互相调用的步骤:
WebView开启JavaScript脚本执行
WebView设置提供JavaScript调用的交互接口
客户端和网页端编写调用对方的代码
具体如下

Android如何调用H5中的方法

想要调用JS方法,那么必须让webView支持

WebSettings webSettings=mWebView.getSettings();
//设置为可调用js方法
webSettings.setJavaScriptEnable(true);

如何调用?
Android调用H5中的方法,直接调用即可,不需要额外的操作。

  1. 调用H5中无参无返回值的方法
  2. 调用H5中带返回值的方法
  3. 调用H5中带参数的方法

调用H5中无参无返回值的方法
H5代码:

...
//无参无返回值的方法
function show(){
  //显示helloworld
  document.getElementById("p").innerHTML="helloworld";
}
...

Java代码中调用H5中的show()方法:
mWebView.loadUrl("JavaScript:show()");

调用H5中带返回值的方法
可以调用mWebView.evaluateJavascript()方法,该方法只在安卓4.4以上版本适用

//Android调用有返回值js方法,安卓4.4以上才能用这个方法
mWebView.evaluateJavascript("sum(1,2)", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String value) {
        Log.d(TAG, "js返回的结果为=" + value);
        Toast.makeText(MainActivity.this, "js返回的结果为=" + value, Toast.LENGTH_LONG).show();
    }
});

调用H5中带参数的方法
有两种情况:
当调用H5中带参数的方法时,势必要传入一个字符串,当传入固定字符串时,用单引号括起来即可;
当传入变量名时,需要用到转义符

//传固定字符串可以直接用单引号括起来
mWebView.loadUrl("javascript:alertMessage('哈哈')");//访问H5里带参数的方法,alertMessage(message)为H5里的方法

//当出入变量名时,需要用转义符隔开
String content="9880";
mWebView.loadUrl("javascript:alertMessage(\""   +content+   "\")"   );

H5如何调用Android中的方法

...
//设置支持js调用java
webView.addJavascriptInterface(new AndroidAndJSInterface(),"Android");
...

/**
 * 自己写一个类,里面是提供给H5访问的方法
 * */
public class AndroidAndJSInterface{

    @JavascriptInterface//一定要写,不然H5调不到这个方法
    public String back() {
        return "我是java里的方法返回值";
    }
}

代码分析:
新建一个类,里面写提供给H5操作的方法,并规定别名。这里新建的class为AndroidAndJSInterface,方法为back(),规定的别名为Android。
在安卓4.2以上可以直接使用@JavascriptInterface注解来声明,定义完这个方法后再调用mWebView.addJavascriptInterface()方法:

H5代码:

function s() {
    //调用原生的方法,Android为约定的别名;back()为原生的方法
    var result=window.Android.back();
    //将返回结果显示在id为p的控件上
    document.getElementById("p").innerHTML=result;
}

完整demo,我的GitHub:https://github.com/FlyStorm/MyAndroidAndH5

注意事项:
1、当自己写html文件时,可能会出现显示乱码,我们需要指定格式:

<head>
    <!--从assert中加载的中文网页会出现乱码,解决办法就是给html指定编码-->
    <meta http-equlv="Content-Type" content="text/html;charset=UTF-8">
    <title>
    </title>
</head>

项目代码为utf-8编码。

2、当H5调用我们的方法时,我们需要把规定的别名传给H5(切记一定不能错),而且我们要在自己的方法里执行H5想要的操作。

webSettings.setJavaScriptEnabled(true);//打开js支持
/**
 * 打开js接口給H5调用,参数1为本地类名,参数2为别名;h5用window.别名.类名里的方法名才能调用方法里面的内容,例如:window.android.back();
 * */
mWebView.addJavascriptInterface(new AndroidAndJSInterface(), "Android");
mWebView.setWebViewClient(new WebViewClient());
mWebView.setWebChromeClient(new WebChromeClient());

3、给H5调用的方法一定要加@JavascriptInterface,不然H5调不到我们的方法

/**
 * 自己写一个类,里面是提供给H5访问的方法
 */
public class AndroidAndJSInterface {

    @JavascriptInterface//一定要写,不然H5调不到这个方法
    public String back() {
        return "我是java里的方法返回值";
    }
}

4、 调用js有参数有返回值的函数时,只有安卓4.4以上才能用webView.evaluateJavascript方法直接拿到返回值;当版本低于4.4的时候,常用的思路是 java调用js方法,js方法执行完毕,再次调用java代码将值返回。
当版本低于4.4的时候:
Java调用js代码

String call = "javascript:sumToJava(1,2)";
webView.loadUrl(call);

js函数处理,并将结果通过调用java方法返回

function sumToJava(number1, number2){
       window.control.onSumResult(number1 + number2)
}

Java在回调方法中获取js函数返回值

@JavascriptInterface
public void onSumResult(int result) {
  Log.i(LOGTAG, "onSumResult result=" + result);
}

5、加载本地assets里的H5界面,要写成android_asset,而不是assets,不然加载不到

以上是根据我的一些理解,做的总结分享,旨在抛砖引玉,希望有更多的志同道合的朋友一起讨论学习,共同进步!

参考文献:
http://www.jianshu.com/p/0b986d6e2e17

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容