转载请标明出处:http://77blogs.com/?p=281
android开发中有经常需要用到android与H5的交互,有必要学一下。
如下图
点击各个按钮代表的意思已经很明显,我就不多说了
1、先看一下布局:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
<?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" android:orientation="vertical" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="Android区域" android:textColor="@android:color/holo_blue_dark" android:textSize="20dp" /> <Button android:id="@+id/btn_android_call_js" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@android:color/holo_blue_dark" android:clickable="true" android:text="android调用js代码" /> <Button android:id="@+id/btn_android_call_js_with_arg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:background="@android:color/holo_blue_dark" android:clickable="true" android:text="android调用js代码并传参" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="js调用android的结果" android:textColor="@android:color/holo_blue_dark" /> <TextView android:id="@+id/js_call_android__result_show" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:textColor="@android:color/holo_blue_dark" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="Web区域" android:textColor="@android:color/holo_blue_dark" android:textSize="20dp" /> <WebView android:id="@+id/web_view" android:layout_width="match_parent" android:layout_height="match_parent"> </WebView> </LinearLayout> </LinearLayout> |
2、编写html页面,并且放在main下的assets资源文件夹下,没有的话请自己创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<html> <head> <meta http-equiv="Content-Type" charset="UTF-8"/> <script type="text/javascript"> //android调用js的方法 function javaCallJs(){ document.getElementById("showmsg").innerHTML = "JAVA调用了JS的无参函数"; } //android调用js的方法 function javaCallJsWithArg(arg){ document.getElementById("showmsg").innerHTML = (arg); } </script> </head> <body> <h3>Web模块</h3> //显示android调用js后显示的结果 <h3 id="showmsg">java代码调用js显示结果</h3> //点击按钮调用android的方法 <input type="button" value="Js调用Java代码" onclick="window.customAndroid.jsCallAndroid()"/> //点击按钮调用android的方法 <input type="button" value="Js调用Java代码并传参数" onclick="window.customAndroid.jsCallAndroidArgs('Js传过来的参数')"/> </body> </html> |
3、主程序:
1 2 3 4 5 6 7 |
WebSettings webSettings = webView.getSettings(); //与js交互必须设置 webSettings.setJavaScriptEnabled(true); //加载网页 webView.loadUrl("file:///android_asset/jsH5.html"); //注入接口 webView.addJavascriptInterface(MainActivity.this, "customAndroid"); |
custonAndroid为自定义字段,需要与下面代码中的字段一样。
<input type=”button” value=”Js调用Java代码” onclick=”window.customAndroid.jsCallAndroid()”/>
webView.addJavascriptInterface有安全漏洞(H5可以调用android本地的所有方法),所以4.2以上还需要使用注解来表明那些方法是js可以调用的,接下来会讲。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
btnAndroidCallJs.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "btnAndroidCallJs onClick"); //javaCallJs为H5中定义的方法 webView.loadUrl("javascript:javaCallJs()"); } }); btnAndroidCallJsWithArg.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "btnAndroidCallJsWithArg onClick"); //javaCallJsWithArg为H5中定义的方法 webView.loadUrl("javascript:javaCallJsWithArg(" + "'Android传过来的参数'" + ")"); } }); |
H5中这两个方法的作用
1 2 3 |
function javaCallJs(){ document.getElementById("showmsg").innerHTML = "JAVA调用了JS的无参函数"; } |
如上html中代码,向id为showmsg的h3大小标题中写入字符串
1 2 3 |
function javaCallJsWithArg(arg){ document.getElementById("showmsg").innerHTML = (arg); } |
同上,只是显示的现象变成了android传过去的字符串了。
js调用android:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@JavascriptInterface public void jsCallAndroid() { Log.d(TAG, "thread is" + Thread.currentThread().getName()); runOnUiThread(new Runnable() { @Override public void run() { tvJsCallAndroidResult.setText("js调用了android的方法"); } }); } @JavascriptInterface public void jsCallAndroidArgs(final String args) { Log.d(TAG, "thread is" + Thread.currentThread().getName()); runOnUiThread(new Runnable() { @Override public void run() { tvJsCallAndroidResult.setText(args); } }); } |
@JavascriptInterface也就是我上面说的注解,4.2以上必须使用这个注解,否则js无法调用本地的方法。本地方法的名称需要与H5中定义的一样。
实践证明,js调用的方法并不是在主线程中,而是在线程名为JavaBridge的线程中。
当我们点击下面webview中的按钮的时候便会执行这两个方法。