0


关于原生android与H5交互的方法

文章目录

原生android与H5交互

前面讲解方法,结尾放代码

android调用H5方法

首先需要一个WebView

/*查找到WebView控件*/
mWebView =(WebView)findViewById(R.id.webView);/*给WebView一个H5的链接,这里使用的是自己启动的Vue项目*/
mWebView.loadUrl("http://10.20.58.190:8081/");/*对WebView进行设置*/WebSettings webSettings = mWebView.getSettings();/*既然要调用H5的方法,那么一定不能禁用JS方法*/
webSettings.setJavaScriptEnabled(true);
  • 方法一:使用WebView的loadUrl()方法,以loadUrl(script)的方式调用

android方法:

/*在某处写入这一行代码即可*/
mWebView.loadUrl("javascript:test1Fun('使用这种方法无法取得返回参数,且会刷新页面,如果js函数有返回值,则页面会仅展示返回值')");

需要H5支持:

/*
这里使用的是Vue,对data里的test1Content 进行了修改
*/test1Fun(str){this.test1Content = str;// return "调用test1Fun成功";}/*
要注意的是,如果使用原生H5,直接在页面的JavaScript标签里写入一个方法即可
但是如果使用vue来写的话,需要将此方法暴露给window,如下
*/mounted(){
    window.test1Fun =this.test1Fun;}

这种方法比较简单,但是缺点在于android无法获取函数的返回值
注:如果调用的函数存在返回值的话,那么H5的页面会只显示返回值

  • 方法二:使用WebView的evaluateJavascript()方法

android方法:

mWebView.evaluateJavascript("test2Fun('使用这种方法可以取得返回参数,且不会刷新页面')",newValueCallback<String>(){@OverridepublicvoidonReceiveValue(String value){
        text2.setText(value);}});

这种方法同样需要H5支持,同上:

test2Fun(str){this.test2Content = str;return"调用test2Fun成功";}/*同样需要暴露到window*/mounted(){
    window.test2Fun =this.test2Fun;}

这种方法比上一种方法更为灵活,且能够获取返回值

H5调用android

  • 方法一:使用WebView的addJavascriptInterface()方法注入对象。

android注入:

/*将JsInteration注入到h5的window.android中*/
mWebView.addJavascriptInterface(newJsInteration(),"android");/*这里实现JsInteration */publicclassJsInteration{@JavascriptInterfacepublicStringJsCallJava1(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方法:

/*这里的url是H5将要进行跳转的链接,使用这个方法进行拦截*/
mWebView.setWebViewClient(newWebViewClient(){@OverridepublicbooleanshouldOverrideUrlLoading(WebView view,String url){if(url.equals("http://10.20.58.190:8081/intercept")){
                    text4.setText("intercept");//                    startActivity(new Intent(MainActivity.this,SecondFragment.class));returntrue;}else{
                    mWebView.loadUrl(url);returnfalse;}}});

H5调用:

location.href ="http://10.20.58.190:8081/intercept";

**注:这里一般是用于拦截链接,如果

shouldOverrideUrlLoading

的返回值为true,则会进行拦截,H5不进行跳转,否则则进行跳转**

  • 方法三:重写 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息。

android方法:

mWebView.setWebChromeClient(newWebChromeClient(){@OverridepublicbooleanonJsAlert(WebView view,String url,String message,JsResult result){if(message.equals("alert")){
                    alert.setText("成功");}returnsuper.onJsAlert(view, url, message, result);}@OverridepublicbooleanonJsConfirm(WebView view,String url,String message,JsResult result){if(message.equals("confirm")){
                    confirm.setText("成功");}returnsuper.onJsConfirm(view, url, message, result);}@OverridepublicbooleanonJsPrompt(WebView view,String url,String message,String defaultValue,JsPromptResult result){if(message.equals("prompt")){
                    prompt.setText("成功");}returnsuper.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:

packagecom.example.study_android_java_javascript;importandroid.os.Bundle;importandroid.view.View;importandroid.webkit.JavascriptInterface;importandroid.webkit.JsPromptResult;importandroid.webkit.JsResult;importandroid.webkit.ValueCallback;importandroid.webkit.WebChromeClient;importandroid.webkit.WebSettings;importandroid.webkit.WebView;importandroid.webkit.WebViewClient;importandroid.widget.Button;importandroid.widget.TextView;importandroidx.appcompat.app.AppCompatActivity;publicclassMainActivityextendsAppCompatActivity{publicstaticfinalString TAG ="MainActivity";privateWebView mWebView;privateTextView text1;privateTextView text2;privateTextView text3;privateTextView text4;privateButton btn1;privateButton btn2;privateButton btn_clear;privateTextView alert;privateTextView confirm;privateTextView prompt;@OverrideprotectedvoidonCreate(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(newView.OnClickListener(){@OverridepublicvoidonClick(View view){
                mWebView.loadUrl("javascript:test1Fun('使用这种方法无法取得返回参数,且会刷新页面,如果js函数有返回值,则页面会仅展示返回值')");}});
        btn2 =(Button)findViewById(R.id.btn2);
        btn2.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(View view){
                mWebView.evaluateJavascript("test2Fun('使用这种方法可以取得返回参数,且不会刷新页面')",newValueCallback<String>(){@OverridepublicvoidonReceiveValue(String value){
                        text2.setText(value);}});}});
        btn_clear =findViewById(R.id.btn_clear);
        btn_clear.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(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(newJsInteration(),"android");
        mWebView.setWebViewClient(newWebViewClient(){@OverridepublicbooleanshouldOverrideUrlLoading(WebView view,String url){if(url.equals("http://10.20.58.190:8081/intercept")){
                    text4.setText("intercept");//                    startActivity(new Intent(MainActivity.this,SecondFragment.class));returntrue;}else{
                    mWebView.loadUrl(url);returnfalse;}}});
        mWebView.setWebChromeClient(newWebChromeClient(){@OverridepublicbooleanonJsAlert(WebView view,String url,String message,JsResult result){if(message.equals("alert")){
                    alert.setText("成功");}returnsuper.onJsAlert(view, url, message, result);}@OverridepublicbooleanonJsConfirm(WebView view,String url,String message,JsResult result){if(message.equals("confirm")){
                    confirm.setText("成功");}returnsuper.onJsConfirm(view, url, message, result);}@OverridepublicbooleanonJsPrompt(WebView view,String url,String message,String defaultValue,JsPromptResult result){if(message.equals("prompt")){
                    prompt.setText("成功");}returnsuper.onJsPrompt(view, url, message, defaultValue, result);}});}//Android调用有返回值js方法publicclassJsInteration{@JavascriptInterfacepublicStringJsCallJava1(String value){
            text3.setText(value);return"调用JsCallJava1成功";}}}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns: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"><WebViewandroid:layout_width="match_parent"android:layout_height="200dp"android:id="@+id/webView"/><Buttonandroid:id="@+id/btn1"android:layout_width="match_parent"android:layout_height="wrap_content"android:textAllCaps="false"android:text="使用webview.loadUrl()调用JavaScript方法"/><TextViewandroid:id="@+id/text1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="暂无返回"/><TextViewandroid:layout_width="match_parent"android:layout_height="20dp"/><Buttonandroid:id="@+id/btn2"android:layout_width="match_parent"android:layout_height="wrap_content"android:textAllCaps="false"android:text="使用webview.evaluateJavascript()调用JS方法"/><TextViewandroid:id="@+id/text2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="暂无返回"/><Buttonandroid:id="@+id/btn_clear"android:layout_width="match_parent"android:layout_height="wrap_content"android:textAllCaps="false"android:text="清除H5的内容"android:layout_marginTop="20dp"/><TextViewandroid:layout_marginTop="10dp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="JavaScript调用Java方法:"/><TextViewandroid:id="@+id/text3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:text="JsCallJava1返回值"/><TextViewandroid:layout_marginTop="10dp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="拦截链接:"/><TextViewandroid:id="@+id/text4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="拦截测试数据"/><TextViewandroid:layout_marginTop="10dp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="拦截弹窗"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:gravity="center"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="alert:"/><TextViewandroid:id="@+id/alert"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text=""/></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:gravity="center"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="confirm:"/><TextViewandroid:id="@+id/confirm"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text=""/></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:gravity="center"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="prompt:"/><TextViewandroid: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>exportdefault{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>
标签: android 交互 webview

本文转载自: https://blog.csdn.net/qq_44027159/article/details/127535628
版权归原作者 z_xfan 所有, 如有侵权,请联系我们删除。

“关于原生android与H5交互的方法”的评论:

还没有评论