Android与H5互调

作者: 飞渡浮舟 | 来源:发表于2017-03-25 18:48 被阅读427次

    请注明出处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的相互调!

    相关文章

      网友评论

      • 追风骚年:上次面试的一个外包就是这么干的😂😂

      本文标题:Android与H5互调

      本文链接:https://www.haomeiwen.com/subject/lgpcottx.html