前端实际项目WebView混编~Android的走向

Android与H5互调

2017-03-25  本文已影响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的相互调!

上一篇 下一篇

猜你喜欢

热点阅读