js 与Android交互分为两种情况:js 调用Android原生方法,Android原生调用 js 方法。
本文将对这两种情况分别讲解,H5 端用 vue
实现。
写个Android例子:
Android布局文件代码:
<?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="com.org.youtu.HtmlActivity"> <Button android:id="@+id/btn_load" android:layout_width="80dp" android:layout_height="wrap_content" android:background="@color/colorPrimaryLight" android:textColor="@color/white_overlay" android:onClick="doClick" android:text="给HTML页面传递数据"/> <WebView android:id="@+id/html_webView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout>
HTML页面代码:
注意:window.callJsFunction = this.callJsFunction 要给原生调用的方法挂载到 window 上面,不然方法无法调用成功,后面不能加括号(),会直接调用此方法
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>首页</title> <!-- 引入组件库 vue.min.js 要在 index.js 之前引入--> <script src="js/vue.min.js"></script> <script src="js/axios.min.js"></script> <!-- 引入样式 --> <link rel="stylesheet" type="text/css" href="css/index.css"> <!-- 引入组件库 --> <script src="js/index.js"></script> </head> <body> <div id="appLogin" class="wrap" style="text-align: center;"> <el-button type="success" @click="onSubmit">传数据到Android后台</el-button> </div> <script type="text/javascript"> var vues = new Vue({ el: '#appLogin', /**-----【数据初始化】-----**/ data() { return { }; }, /**-----【方法启动执行】-----**/ mounted() { //将要给原生调用的方法挂载到 window 上面 window.callJsFunction = this.callJsFunction }, /**-----【方法列表】-----**/ methods: { onSubmit(){ /**-----【HTML调用Android后台方法】-----**/ window.login.SendDataFromHtml("我是从HTML中传过来的数据!"); }, callJsFunction(arg) { this.$message.success(arg); }, } }) </script> </body> </html>
逻辑处理Java代码:
public class HtmlActivity extends AppCompatActivity { private WebView html_webView; @SuppressWarnings("unchecked") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //窗口布局到手机最上方 this.requestWindowFeature(Window.FEATURE_NO_TITLE); this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_html); html_webView = this.findViewById(R.id.html_webView); html_webView.getSettings().setJavaScriptEnabled(true); //启用javascript支持 用于访问页面中的javascript html_webView.getSettings().setAllowFileAccess(true); //设置在WebView内部是否允许访问文件 html_webView.loadUrl("file:///android_asset/login.html"); html_webView.addJavascriptInterface(HtmlActivity.this,"login"); } /**【点击事件】**/ public void doClick(View view){ switch (view.getId()){ case R.id.btn_load: String arg = "我是Android中定义的字段数据!"; //html_webView.loadUrl("javascript:callJsFunction('我是Android中定义的字段数据!')");//调用HTML中的方法,传送数据到前端 html_webView.loadUrl("javascript:callJsFunction('" + arg + "')");//调用HTML中的方法,传送数据到前端 break; } } @android.webkit.JavascriptInterface public void SendDataFromHtml(String data){ Log.e("HTML中传过来的数据:" , data); Toast.makeText(HtmlActivity.this,data,Toast.LENGTH_LONG).show(); } }
webview的几种加载方式:
//方式1. 加载一个网页: webView.loadUrl("http://www.baidu.com/");
//访问网页
webView.loadUrl("https://www.baidu.com/");
//系统默认会通过手机浏览器打开网页,为了能够直接通过WebView显示网页,则必须设置
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//使用WebView加载显示url
view.loadUrl(url);
//返回true
return true;
}
});
//方式2:加载apk包中的html页面 webView.loadUrl("file:///android_asset/test.html"); //方式3:加载手机本地的html页面 webView.loadUrl("content://com.android.levi/sdcard/test.html");
webview的Settings常见设置
// webview启用javascript支持 用于访问页面中的javascript settings.setJavaScriptEnabled(true); //设置WebView缓存模式 默认断网情况下不缓存 settings.setCacheMode(WebSettings.LOAD_DEFAULT); /** * LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据 * LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。 * LOAD_NO_CACHE: 不使用缓存,只从网络获取数据. * LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。 */ //断网情况下加载本地缓存 settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);} //让WebView支持DOM storage API settings.setDomStorageEnabled(true); //让WebView支持缩放 settings.setSupportZoom(true); //启用WebView内置缩放功能 settings.setBuiltInZoomControls(true); //让WebView支持可任意比例缩放 settings.setUseWideViewPort(true); //让WebView支持播放插件 settings.setPluginState(WebSettings.PluginState.ON); //设置WebView使用内置缩放机制时,是否展现在屏幕缩放控件上 settings.setDisplayZoomControls(false); //设置在WebView内部是否允许访问文件 settings.setAllowFileAccess(true); //设置WebView的访问UserAgent settings.setUserAgentString(String string); //设置脚本是否允许自动打开弹窗 settings.setJavaScriptCanOpenWindowsAutomatically(true); // 加快HTML网页加载完成速度 if (Build.VERSION.SDK_INT >= 19) { settings.setLoadsImagesAutomatically(true); } else { settings.setLoadsImagesAutomatically(false); } // 开启Application H5 Caches 功能 settings.setAppCacheEnabled(true); // 设置编码格式 settings.setDefaultTextEncodingName("utf-8");
部分参考:https://www.jianshu.com/p/e8eeec4e8d71
注意事项:html_webView.loadUrl("javascript:callJsFunction('" + arg + "')"); //Android调用HTML中的方法,传送数据到前端
传递的参数 arg ,我在运行试发现一个问题:"( ' " + arg + " ' )",如果在 arg 的两边不加 ' 号会报错:Uncaught SyntaxError: missing
在网上找了一下答案说:js方法传递参数时,如果参数是string类型,需要在参数前后加 " "
运行结果: