关于原生android与H5交互的方法
文章目录
原生android与H5交互
前面讲解方法,结尾放代码
android调用H5方法
首先需要一个WebView
mWebView = (WebView) findViewById(R.id.webView);mWebView.loadUrl("http://10.20.58.190:8081/");WebSettings webSettings = mWebView.getSettings();webSettings.setJavaScriptEnabled(true);
- 方法一:使用WebView的loadUrl()方法,以loadUrl(script)的方式调用
android方法:
mWebView.loadUrl("javascript:test1Fun('使用这种方法无法取得返回参数,且会刷新页面,如果js函数有返回值,则页面会仅展示返回值')");
需要H5支持:
test1Fun(str){this.test1Content = str;// return "调用test1Fun成功";}mounted(){window.test1Fun = this.test1Fun;}
这种方法比较简单,但是缺点在于android无法获取函数的返回值
注:如果调用的函数存在返回值的话,那么H5的页面会只显示返回值
- 方法二:使用WebView的evaluateJavascript()方法
android方法:
mWebView.evaluateJavascript("test2Fun('使用这种方法可以取得返回参数,且不会刷新页面')", new ValueCallback<String>() {@Overridepublic void onReceiveValue(String value) {text2.setText(value);}});
这种方法同样需要H5支持,同上:
test2Fun(str){this.test2Content = str;return "调用test2Fun成功";}mounted(){window.test2Fun = this.test2Fun;}
这种方法比上一种方法更为灵活,且能够获取返回值
H5调用android
- 方法一:使用WebView的addJavascriptInterface()方法注入对象。
android注入:
mWebView.addJavascriptInterface(new JsInteration(), "android");public class JsInteration { @JavascriptInterface public String JsCallJava1(String value) { text3.setText(value); return "调用JsCallJava1成功"; } }
H5调用:
useJsCallJava1(){ let a = window.android.JsCallJava1("我是JsCallJava1的返回值"); this.JsCallJava1Content = a; }
这种方式运用最为广泛,一些企业级的项目都是以此为基础搭建H5调用android的桥方法,当然,为了防止注入过多的方法,参数一般是JSON字符串格式,在android获取到参数后,会将其转换为JSON,然后根据其状态,进行后续的操作反馈。
- 方法二:使用WebViewClient 的shouldOverrideUrlLoading()方法回调拦截请求。
android方法:
mWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.equals("http://10.20.58.190:8081/intercept")) { text4.setText("intercept");// startActivity(new Intent(MainActivity.this,SecondFragment.class)); return true; } else { mWebView.loadUrl(url); return false; } } });
H5调用:
location.href = "http://10.20.58.190:8081/intercept";
注:这里一般是用于拦截链接,如果shouldOverrideUrlLoading
的返回值为true,则会进行拦截,H5不进行跳转,否则则进行跳转
- 方法三:重写 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息。
android方法:
mWebView.setWebChromeClient(new WebChromeClient(){ @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result){ if (message.equals("alert")){ alert.setText("成功"); } return super.onJsAlert(view, url, message, result); } @Override public boolean onJsConfirm(WebView view, String url, String message, JsResult result) { if (message.equals("confirm")){ confirm.setText("成功"); } return super.onJsConfirm(view, url, message, result); } @Override public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { if (message.equals("prompt")){ prompt.setText("成功"); } return super.onJsPrompt(view, url, message, defaultValue, result); } });
H5触发:
useJsCallJava3(judge){ if(judge == 1){ alert('alert') } if(judge == 2){ confirm('confirm') } if(judge == 3){ prompt('prompt') } }
此方法将会监听三种弹窗,用户可以根据弹窗内容进行判断,但是请注意
如果在android拦截后,return了true,则会默认客户会对弹窗进行处理,所以我们要对弹窗进行额外处理,否则H5页面就会卡死。
因此这种方法为了避免麻烦,还是少用为好,并且不对弹窗进行拦截,仅监听即可。
最后,完整的demo如下
MainActivity.java:
package com.example.study_android_java_javascript;import android.os.Bundle;import android.view.View;import android.webkit.JavascriptInterface;import android.webkit.JsPromptResult;import android.webkit.JsResult;import android.webkit.ValueCallback;import android.webkit.WebChromeClient;import android.webkit.WebSettings;import android.webkit.WebView;import android.webkit.WebViewClient;import android.widget.Button;import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity { public static final String TAG = "MainActivity"; private WebView mWebView; private TextView text1; private TextView text2; private TextView text3; private TextView text4; private Button btn1; private Button btn2; private Button btn_clear; private TextView alert; private TextView confirm; private TextView prompt; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text1 =findViewById(R.id.text1); text2 =findViewById(R.id.text2); text3 = findViewById(R.id.text3); text4 = findViewById(R.id.text4); alert = findViewById(R.id.alert); confirm = findViewById(R.id.confirm); prompt = findViewById(R.id.prompt); btn1 = (Button) findViewById(R.id.btn1); btn1.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View view) { mWebView.loadUrl("javascript:test1Fun('使用这种方法无法取得返回参数,且会刷新页面,如果js函数有返回值,则页面会仅展示返回值')"); } }); btn2 = (Button) findViewById(R.id.btn2); btn2.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View view) { mWebView.evaluateJavascript("test2Fun('使用这种方法可以取得返回参数,且不会刷新页面')", new ValueCallback<String>() { @Override public void onReceiveValue(String value) { text2.setText(value); } }); } }); btn_clear = findViewById(R.id.btn_clear); btn_clear.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View view) { mWebView.loadUrl("javascript:clearContent()"); text2.setText("暂无返回"); } }); mWebView = (WebView) findViewById(R.id.webView); mWebView.loadUrl("http://10.20.58.190:8081/"); WebSettings webSettings = mWebView.getSettings(); webSettings.setJavaScriptEnabled(true); mWebView.addJavascriptInterface(new JsInteration(), "android"); mWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.equals("http://10.20.58.190:8081/intercept")) { text4.setText("intercept");// startActivity(new Intent(MainActivity.this,SecondFragment.class)); return true; } else { mWebView.loadUrl(url); return false; } } }); mWebView.setWebChromeClient(new WebChromeClient(){ @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result){ if (message.equals("alert")){ alert.setText("成功"); } return super.onJsAlert(view, url, message, result); } @Override public boolean onJsConfirm(WebView view, String url, String message, JsResult result) { if (message.equals("confirm")){ confirm.setText("成功"); } return super.onJsConfirm(view, url, message, result); } @Override public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { if (message.equals("prompt")){ prompt.setText("成功"); } return super.onJsPrompt(view, url, message, defaultValue, result); } }); } //Android调用有返回值js方法 public class JsInteration { @JavascriptInterface public String JsCallJava1(String value) { text3.setText(value); return "调用JsCallJava1成功"; } }}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center_horizontal"> <WebView android:layout_width="match_parent" android:layout_height="200dp" android:id="@+id/webView" /> <Button android:id="@+id/btn1" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAllCaps="false" android:text="使用webview.loadUrl()调用JavaScript方法"/> <TextView android:id="@+id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="暂无返回"/> <TextView android:layout_width="match_parent" android:layout_height="20dp"/> <Button android:id="@+id/btn2" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAllCaps="false" android:text="使用webview.evaluateJavascript()调用JS方法"/> <TextView android:id="@+id/text2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="暂无返回"/> <Button android:id="@+id/btn_clear" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAllCaps="false" android:text="清除H5的内容" android:layout_marginTop="20dp"/> <TextView android:layout_marginTop="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="JavaScript调用Java方法:"/> <TextView android:id="@+id/text3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="JsCallJava1返回值"/> <TextView android:layout_marginTop="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="拦截链接:"/> <TextView android:id="@+id/text4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="拦截测试数据"/> <TextView android:layout_marginTop="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="拦截弹窗"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="alert:"/> <TextView android:id="@+id/alert" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=""/> LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="confirm:"/> <TextView android:id="@+id/confirm" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=""/> LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="prompt:"/> <TextView android:id="@+id/prompt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=""/> LinearLayout>LinearLayout>
indexVue.vue
<template> <div class="box"> <div class="test1"> <h3 title="123">{{test1}}</h3> <h4>测试内容:{{test1Content}}</h4> </div> <div class="test2"> <h3>{{test2}}</h3> <h4>测试内容:{{test2Content}}</h4> </div> <button @click="useJsCallJava1">调用Java方法:JsCallJava1</button> <h4>返回数据:{{JsCallJava1Content}}</h4> <button @click="useJsCallJava2">拦截链接</button> <h4> </h4> <button @click="useJsCallJava3(1)">测试拦截alert</button> <button @click="useJsCallJava3(2)">测试拦截confirm</button> <button @click="useJsCallJava3(3)">测试拦截prompt</button> </div></template><script>export default { data(){ return { test1:"Java使用webview.loadUrl()调用JavaScript方法", test1Content:"", test2:"Java使用webview.evaluateJavascript()调用JavaScript方法", test2Content:"", JsCallJava1Content:"", }; }, methods:{ test1Fun(str){ this.test1Content = str; // return "调用test1Fun成功"; }, test2Fun(str){ this.test2Content = str; return "调用test2Fun成功"; }, clearContent(){ this.test1Content = ""; this.test2Content = ""; }, useJsCallJava1(){ let a = window.android.JsCallJava1("我是JsCallJava1的返回值"); this.JsCallJava1Content = a; }, useJsCallJava2(){ location.href = "intercept"; }, useJsCallJava3(judge){ if(judge == 1){ alert('alert') } if(judge == 2){ confirm('confirm') } if(judge == 3){ prompt('prompt') } } }, mounted(){ window.test1Fun = this.test1Fun; window.test2Fun = this.test2Fun; window.clearContent = this.clearContent; }}</script><style scoped> h3{ color: blue; } h4{ color: red; }</style>
来源地址:https://blog.csdn.net/qq_44027159/article/details/127535628
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341