android原生和H5交互(转)

自作多情 提交于 2020-02-01 09:11:28

最近在左一个Android原生的H5混合开发的APP,之前还没有好好的总结一下Android原生 和 H5 之间交互的方法,这里来总结一下:

1、hybrid通信,主要就是前端的js和我们Android端的通信 这是最基本JS和Java 的通信方式:
这里我们分四块来讲:
(1)、js调用android原生的代码(不传递参数)
(2)、js调用android原生的代码(传递参数)
(3)、android原生调用JS的代码(不传递参数)
(4)、android原生调用JS的代码(传递参数)

好的我们这里先来创建一个工程:
在工程的main文件夹下创建一个文件夹assets ,然后把写好的H5页面放入该文件夹中,H5页面代码如下:

  <pre name="code" class="html"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml">  
<head>  
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
    <title>这里是一个H5页面</title>  
</head>  
  
<body>  
<p id="ptext">点击按键0 执行android中的 public void click0(){} 方法</p>  
<Button id="buttonId0" class="buttonClass" onclick="javascript:button.click0()">按键0</Button>  
<p>点击按键1 执行android中的 public void click0(String data1,String data2){}方法</p>  
<Button id="buttonId1" class="buttonClass" onclick="javascript:button.click0('参数1','参数2')">按键1</Button>  
  
<script>  
        function setRed(){  
        //这个方法设置 id 为 ptext 的元素的背景色为红色  
        var a = document.getElementById('ptext');  
        a.style.backgroundColor="#F00";  
    }  
    function setColor(color,text){  
        //这个方法设置 id 为 ptext 的元素的背景色为指定颜色  
        //设置 id 为 ptext 的元素的内容为text  
        var a = document.getElementById('ptext');  
        a.style.backgroundColor=color;  
        a.innerHTML = text;  
    }  
    </script>  
</body>  

上边是一个简单的H5页面,其中包含连个按钮,点击按钮触发android 原生的方法;里边还有两个JS 方法,其中包括两个,主要用于给android原生去调用。

回到 activity_main.xml中,布局如下:

<?xml version="1.0" encoding="utf-8"?>  
<RelativeLayout 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="manyizilin.com.androidh5.MainActivity">  
  
    <WebView android:id="@+id/webview"  
        android:layout_height="match_parent"  
        android:layout_width="match_parent"  
        />  
    <LinearLayout android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:layout_alignParentBottom="true"  
        android:orientation="horizontal">  
        <Button android:id="@+id/red"  
            android:layout_height="wrap_content"  
            android:layout_width="wrap_content"  
            android:layout_weight="1"  
            android:text="背景变成红色"/>  
        <Button android:id="@+id/color"  
            android:layout_height="wrap_content"  
            android:layout_width="wrap_content"  
            android:layout_weight="1"  
            android:text="背景色可以自定义"/>  
    </LinearLayout>  
</RelativeLayout>  

主要包含一个WebView控件和两个按钮,点击按钮可以触发上边H5页面中的JS方法
最后看一下MainActivity的代码:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{  
  
    private WebView webView;  
    private Button redButton,colorButton;  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        webView = (WebView)findViewById(R.id.webview);  
        redButton = (Button)findViewById(R.id.red);  
        colorButton = (Button)findViewById(R.id.color);  
        redButton.setOnClickListener(this);  
        colorButton.setOnClickListener(this);  
        initWebView();  
        webView.loadUrl("file:///android_asset/android&h5Text0.html"); //加载assets文件中的H5页面  
    }  
  
    /** 
     *初始化WebView 
     */  
  @SuppressLint("JavascriptInterface")  //添加该字段  
 private void initWebView(){  
        WebSettings settings =  webView.getSettings();  
        settings.setJavaScriptEnabled(true);  //设置运行使用JS  
        ButtonClick click = new ButtonClick();  
        //这里添加JS的交互事件,这样H5就可以调用原生的代码  
        webView.addJavascriptInterface(click,click.toString());  
    }  
  
    @Override  
    public void onClick(View v) {  
        switch (v.getId()){  
            case R.id.red:  //调用JS中的无参数方法  
                webView.loadUrl("javascript:setRed()");  
                break;  
            case R.id.color://调用JS中的有参数方法  
                webView.loadUrl("javascript:setColor('#00f','这是android 原生调用JS代码的触发事件')");  
                break;  
        }  
    }  
  
    /** 
     * H5页面按钮点击触发事件 
     */  
    class ButtonClick{  
  
        //这是 button.click0() 的触发事件  
        //H5调用方法:javascript:button.click0()  
        @JavascriptInterface  
        public void click0(){  
           show("title","");  
        }  
  
        //这是 button.click0() 的触发事件,可以传递待参数  
        //H5调用方法:javascript:button.click0('参数1','参数2')  
        @JavascriptInterface  
        public void click0(String data1,String data2){  
            show(data1,data2);  
        }  
  
  
        @JavascriptInterface  //必须添加,这样才可以标志这个类的名称是 button  
        public String toString(){  
            return "button";  
        }  
  
        private void show(String title,String data){  
            new AlertDialog.Builder(getWindow().getContext())  
                    .setTitle(title)  
                    .setMessage(data)  
                    .setPositiveButton("确定",null)  
                    .create().show();  
        }  
    }  
}  

好了上边的代码就是这样,接下来我们来详细解释一下:

首先我们拿到了一个WebView,初始化webView,在webView中想要运行JS脚本,必须要设置:

WebSettings settings =  webView.getSettings(;  
settings.setJavaScriptEnabled(true);  //设置运行使用JSeang  

加载 assets中的H5页面:

webView.loadUrl("file:///android_asset/android&h5Text0.html"); //加载assets文件中的H5页面

接下来写一个类,专门用于JS调用;

 记得必须写  写toString() 方法,放回来的结果和 JS中调用的方法的类名一致:

比如:在这个例子中JS调用原生是使用 JavaScript:button.click0(); 注意一下,这个的 button 和Java中响应的类的toSring() 方法的返回值是一样的。

@JavascriptInterface 
         public String toString(){             return "button";         }

JavaScript:button.click0(); 其中的 click0 和java响应类的触发方法的方法名是一致的。方法的权限都是 public 。

**  
     * H5页面按钮点击触发事件  
     */  
    class ButtonClick{  
  
        //这是 button.click0() 的触发事件  
        //H5调用方法:javascript:button.click0()  
        @JavascriptInterface  
        public void click0(){  
           show("title","");  
        }  
  
        //这是 button.click0() 的触发事件,可以传递待参数  
        //H5调用方法:javascript:button.click0('参数1','参数2')  
        @JavascriptInterface  
        public void click0(String data1,String data2){  
            show(data1,data2);  
        }  
  
  
        @JavascriptInterface  //必须添加,这样才可以标志这个类的名称是 button //在android 4.2之前不需要添加,在4.2之后需要添加  
        public String toString(){  
            return "<strong>button</strong>";  
        }  
  
        private void show(String title,String data){  
            new AlertDialog.Builder(getWindow().getContext())  
                    .setTitle(title)  
                    .setMessage(data)  
                    .setPositiveButton("确定",null)  
                    .create().show();  
        }  
    }  

好了,准备得差不多了

(1)、js调用android原生的代码(不传递参数)/ (2)、js调用android原生的代码(传递参数)
然后通过WebView的addJavascriptInterface方法去注入一个我们自己写的interface。

 ButtonClick click = new ButtonClick();   
  //这里添加JS的交互事件,这样H5就可以调用原生的代码  
  webView.addJavascriptInterface(click,click.toString());  

这里来说明一下 addJavascriptInterface 这个方法,前一个参数是触发的对象,后一个参数是这对象的标志,需要在这个类的内部添加下面的代码,这样JS才可以识别这个类的内部方法:

@JavascriptInterface  //@JavascriptInterface必须添加,这样才可以标志这个类的名称是 button //在android 4.2之前不需要添加,在4.2之后需要添加  
  public String toString(){  
      return "button";  
  }  

现在点击H5页面中的 按键0 就可以触发事件 ButtonClick 类中的 click0() 方法了,点击 按键1 就可以触发事 ButtonClick 类中的 click0(String data1,String data2) 方法了

(3)、android原生调用JS的代码(不传递参数)

   在加载 H5页面结束后,调用   webView.loadUrl("javascript:setRed()");  那么就可以调用 该页面中的 setRed() 这个JS方法了

(4)、android原生调用JS的代码(传递参数)

在加载 H5页面结束后,调用
webView.loadUrl(“javascript:setColor(’#00f’,‘这是android 原生调用JS代码的触发事件’)”);
那么就可以调用 该页面中的 setColor(color,text) 这个JS方法了

————————————————
版权声明:本文为CSDN博主「ManYiZilin」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ManYiZilin/article/details/69258032

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!