Android与H5互调

请注明出处http://blog.csdn.net/qq_23179075/article/details/65940411

298978.jpg

——现在主流的APP微信,微博,微商,QQ空间等大量的软件都使用了内嵌H5页面的开发方式,如果一个牛逼的公司都在用这些,这个时候我们就需要跟上他们的脚步了,了解Android如何跟H5交互。现在有些外包公司,也是直接采用Android内嵌H5模式开发,便于在IOS上直接复用页面,最终解决成本,和提高开发效率。

本文主要通过下面几个例子来讲述如何使用Android与H5的互调

(要使用H5肯定要用到Android中的WebView组件,如何使用WebView请自行百度、Google)

1.Android代码与Js代码互调:

首先准备HTML文件(文件需要放在assets文件夹下):
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <style>
        #content{
            color:#FF4567;
            font-size:40px;
        }
    </style>
    <script type="text/javascript">
    function javaCallJs(arg){
         document.getElementById("content").innerHTML =
             ("欢迎:"+arg );
    }
    </script>
</head>
<body>
<div align="left" id="content"></div>
<div align="left">这是H5页面</div>
<p><img width="240" height="320"
        src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1490433744477&di=62977511a6e3e7d076629e2114005b0a&imgtype=0&src=http%3A%2F%2Fc.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2F6f061d950a7b0208e95284e160d9f2d3572cc813.jpg">
</p>
<!--调用Android原生代码:
    onclick = "window.+Android传过来的对象名.+对象中的方法"
-->
<input type="button" value="点击Android被调用" onclick="window.Android.showToast()"/>
</body>
</html>

1.1 Android中调用Js代码:

我们这里使用一个登录的例子(布局文件很简单,这里就不上代码了,直接看java代码吧!)

JavaAndJsCall.java

public class JavaAndJsCall extends AppCompatActivity implements View.OnClickListener {
    private EditText etname;
    private EditText etpassword;
    private Button btnlogin;
    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_java_and_js_call);
        initViews();
        initListener();
    }

    /**
     * 初始化界面
     */
    private void initViews() {
        this.btnlogin = (Button) findViewById(R.id.btn_login);
        this.etpassword = (EditText) findViewById(R.id.et_password);
        this.etname = (EditText) findViewById(R.id.et_name);
        //初始化WebView
        initWebView();
    }

    /**
     * 初始化监听器
     */
    private void initListener() {
        btnlogin.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        login();
    }

    /**
     * 登录
     */
    private void login() {
        String name = etname.getText().toString().trim();
        String password = etpassword.getText().toString().trim();
        if (TextUtils.isEmpty(name) || TextUtils.isEmpty(password)) {//输入框判空
            Toast.makeText(this, "用户或密码不能为空!", Toast.LENGTH_SHORT).show();
        } else {
            loginSuccess(name);
        }
    }

    /**
     * 登录成功后调用
     * @param name
     */
    private void loginSuccess(String name) {
       /**
         * 关键代码:
         * 我们要调用H5页面的Js代码(其实就是调用JS中的方法)
         * 就是通过这种形式:javascript:Js文件中的方法名(参数) 
         * 下面的javaCallJs();必须是JS代码中方法
         * 如果参数是变量,就使用拼接字符串方式传参:如下↓↓↓
         */
        webView.loadUrl("javascript:javaCallJs('" + name + "')");
        //登录成功后将H5页面加载到本界面
        setContentView(webView);
    }
    @SuppressLint({"SetJavaScriptEnabled"})
    private void initWebView() {
        webView = new WebView(this);
        WebSettings settings = webView.getSettings();
        //设置支持javaScript脚步语言
        settings.setJavaScriptEnabled(true);
        //支持双击-前提是页面要支持才显示
        settings.setUseWideViewPort(true);
        //支持缩放按钮-前提是页面要支持才显示
        settings.setBuiltInZoomControls(true);
        //设置客户端-不跳转到默认浏览器中
        webView.setWebViewClient(new WebViewClient());
        //加载网页地址
        webView.loadUrl("file:///android_asset/index.html");
    }
}
上面代码中需要使用到的本地Html页面:(要加载本地HTML文件,文件需要放在assets文件夹下,然后通过webView.loadUrl("file:///android_asset/index.html");加载!),注释很详细,其他的就直接看注释吧!

运行效果:

AndroidCallJs.gif
上图可以看到我登录的用户名通过Java代码传入到了H5页面并且显示出来!

1.2 H5页面调用Android原生代码:

Html页面还是之前那个页面,页面中有这样一句代码:
<!--调用Android原生代码:
    onclick = "window.+Android传过来的对象名.+对象中的方法"
-->
<input type="button" value="点击Android被调用" onclick="window.Android.showToast()"/>
在JS中要调用Android原生代码,只需要在初始化WebView时加上下面的代码:
        /**
         * Js中调用Android原生代码核心代码:
         * 该方法传入两个参数:1.被调用的类;2.JS中被调用类的实例对象名字
         * 对象名可以随意取,但是必须和H5页面中onclick的名字对应
         */
        webView.addJavascriptInterface(new AndroidAndJsInterface(), "Android");
然后创建被调用的类AndroidAndJsInterface;
    /**
     * Js中调用的类
     */
    private class AndroidAndJsInterface {
        /**
         * Js中调用的方法
         */
        @JavascriptInterface
        public void showToast() {
            Toast.makeText(JavaAndJsCall.this, "我是原生代码!", Toast.LENGTH_SHORT).show();
        }
    }

注意了!注意了!注意了: 如果要让类中的方法被JS调用需要在方法上加上注解: "@JavascriptInterface" 请仔细看上面代码↑↑↑

(如果不想加注解,也可以把你的目标SDK设置为16 targetSdkVersion = 16,但是不推荐这样使用)

完整代码(三个点是省略代码跟上面相同):

public class JavaAndJsCall extends AppCompatActivity implements View.OnClickListener {
    ...
    ...
    ...
    @SuppressLint({"AddJavascriptInterface", "SetJavaScriptEnabled"})
    private void initWebView() {
        ...
        ...
        ...
        /**
         * Js中调用Android原生代码核心代码:
         * 该方法传入两个参数:1.被调用的类;2.JS中被调用类的实例对象名字
         */
        webView.addJavascriptInterface(new AndroidAndJsInterface(), "Android");
        webView.loadUrl("file:///android_asset/index.html");
    }
    /**
     * Js中调用的类
     */
    private class AndroidAndJsInterface {
        /**
         * Js中调用的方法
         */
        @JavascriptInterface
        public void showToast() {
            Toast.makeText(JavaAndJsCall.this, "我是原生代码!", Toast.LENGTH_SHORT).show();
        }
    }
}

运行效果:

JsCallAndroid.gif

2.下面看一个实例:通过H5页面调用视频播放器

H5页面代码:video.html
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <style>
        #playVideo{
            color:#FF4567;
            font-size:40px;
        }
    </style>
    <script>
        var play = function (){
            var videoId = "65411";
            var title = "神偷奶爸3预告片";
            var videoUrl = "http://vfx.mtime.cn/Video/2017/03/15/mp4/170315003647537910.mp4";
            javascript:android.playVideo(videoId,title,videoUrl);
        }
    </script>
</head>
<body>
<div align="center">这是H5页面</div>
<!--调用Android原生代码:
    onclick = "window.+Android传过来的对象名.+对象中的方法"
-->
<input id="playVideo" type="button" value="点击播放视频" onclick="play()"/>
</body>
</html>
布局文件:activity_js_call_java_video.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.androidandh5.JsCallJavaVideoActivity">
    <WebView
        android:id="@+id/web_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

java代码:JsCallJavaVideoActivity.java

public class JsCallJavaVideoActivity extends AppCompatActivity {
    private WebView webview;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_js_call_java_video);
        initViews();
    }
    @SuppressLint({"SetJavaScriptEnabled", "AddJavascriptInterface"})
    private void initViews() {
        this.webview = (WebView) findViewById(R.id.web_view);
        WebSettings settings = this.webview.getSettings();
        settings.setJavaScriptEnabled(true);
        //设置客户端-不跳转到默认浏览器中
        this.webview.setWebViewClient(new WebViewClient());
        /**
         * Js中调用Android原生代码核心代码:
         * 该方法传入两个参数:1.被调用的类;2.JS中被调用类的实例对象名字
         */
        this.webview.addJavascriptInterface(new PlayVideoInterface(),"android");
        //加载本地H5页面
        this.webview.loadUrl("file:///android_asset/video.html");
    }
    private class PlayVideoInterface {
        /**
         * 播放视频
         * @param id 视频ID
         * @param title 视频标题
         * @param videoUrl 视频url地址
         */
        @JavascriptInterface
        public void playVideo(int id,String title,String videoUrl){
            Intent intent = new Intent();
            intent.setDataAndType(Uri.parse(videoUrl),"video/*");
            startActivity(intent);
        }
    }
}

运行效果:

JsCallAndroidVideo.gif

起始原生Android中与H5互调 本质是:Java代码和JavaScript的相互调!

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

推荐阅读更多精彩内容