博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WebView与Javascript交互及JS的注入
阅读量:6844 次
发布时间:2019-06-26

本文共 5036 字,大约阅读时间需要 16 分钟。

img_132368f26e10968755fca86391911733.png
本篇目录

前言

本篇讲解Java代码和Javascript代码的相互调用以及JS代码在Java中是如何动态的注入WebView中。一些通用配置在第一部分中说明。


一、Java 调用 JS 中函数

1.添加权限(这里使用资源目录下写好的html文件)
2.webView配置
...// 省略掉findView..webviewmWebView.getSettings().setJavaScriptEnabled(true);
3.利用webViewloadUrl()方法调用JS中函数

注意调用的函数前面添加javascript:

...btn_invoke_js1.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View view) {        // 调用JS中无参数的函数        mWebView.loadUrl("javascript:javacalljs()");        mWebView.loadUrl("javascript:javacalljswith(\"JAVA调用了JS的有参函数\")");        }    });...

二、JS 调用 Java 中方法

1.添加js的回调接口

第一个参数是接收回调的类,这里写成当前的类,接下来会在当前类中添加被js调用的方法。obj为别名,和js中保持一致。

mWebView.addJavascriptInterface(this, "obj");
2.java中添加被js调用的方法。

<font color="red">注意一定不要忘记添加@JavascriptInterface</font>这里的方法和web.html中的window.obj.localMethods('Incoming parameters')保持一致。

...@JavascriptInterfacepublic void localMethods(String arg) {    Log.i(TAG, "This method is called!");    Toast.makeText(this, "This method is called!", Toast.LENGTH_SHORT).show();}

三、(重点)Java 中动态注入 JS

1.注入JS方法

这里注入时机是onPageFinished()后;注入的JS是一个alert为例。

public class JsInjectionActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        ...          InsideWebViewClient mInsideWebViewClient = new InsideWebViewClient();          mWebView.setWebChromeClient(new WebChromeClient());        mWebView.setWebViewClient(mInsideWebViewClient);        WebSettings webSettings = mWebView.getSettings();        webSettings.setJavaScriptEnabled(true);        mWebView.addJavascriptInterface(JsInjectionActivity.this, "obj");        mWebView.loadUrl("file:///android_asset/web.html");        ...    }        private class InsideWebViewClient extends WebViewClient {        @Override        public void onPageFinished(WebView view, String url) {            mWebView.loadUrl("javascript:" + "window.alert('Js injection success')" );            super.onPageFinished(view, url);        }    }}...

注意:以上注入的js包含一个alert,写完后可能会发现alert没有弹出来。这时要去检查myWebView.setWebChromeClient(new WebChromeClient());是否设置了。

2.(重点)注入的js导致的问题或可能出现的问题
  1. 注入js可能会导致加载的html5页面总是一直在加载中,加载很慢或干脆加载不出来,这个问题不是针对所有的html5可能在某些网页上会遇到这个问题;
  2. 注入JS后回调函数没有执行到;

解决方法:

@Override    protected void onPause(){        super.onPause();          mWebView.pauseTimers();        if(isFinishing()){            mWebView.loadUrl("about:blank");            setContentView(new FrameLayout(this));        }    }      @Override    protected void onResume(){        super.onResume();        mWebView.resumeTimers();    }

调用webView.loadUrl("about:blank");该方法使得webView只回执一个白色背景,并且释放之前加载页面时使用的资源,并停止之前javascript的执行

pauseTimers, onPause 停止解析,javascript执行等操作.区别是 onPause 只作用于调用它的WebView,而 pauseTimers 作用于当前应用中所有的WebView

resumeTimers, onResume 恢复解析,javascript执行等操作.区别是 onResume 只作用于调用它的WebView,而 resumeTimers 作用于当前应用中所有的WebView。

3.当压缩后的JS注入到webView中时,注入没有生效

我的解决方式:

JS格式化后或是非压缩状态注入成功,不知道别人有没有遇到过类似问题,或者是其它原因,这里有疑问,如果有遇到相同问题的,欢迎一起交流。

在线js格式化,缩进方式选择:4个空格缩进


四、完整代码

完整代码,不包含js注入遇到的问题部分,自行加入。

1. web.html文件

文件路径:..src/main/assets/web.html

    
HTML 内容显示

内容显示

2. JsInjectionActivity.java文件
public class JsInjectionActivity extends Activity {    private static final String TAG = JsInjectionActivity.class.getSimpleName();    private WebView mWebView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button btn_invoke_js1 = (Button) findViewById(R.id.btn_invoke_js1);        Button btn_invoke_js2 = (Button) findViewById(R.id.btn_invoke_js2);        mWebView = (WebView) findViewById(R.id.webview);        InsideWebViewClient mInsideWebViewClient = new InsideWebViewClient();        mWebView.setWebChromeClient(new WebChromeClient());        mWebView.setWebViewClient(mInsideWebViewClient);        WebSettings webSettings = mWebView.getSettings();        webSettings.setJavaScriptEnabled(true);        mWebView.addJavascriptInterface(JsInjectionActivity.this, "obj");        mWebView.loadUrl("file:///android_asset/web.html");        btn_invoke_js1.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                mWebView.loadUrl("javascript:javacalljs()");            }        });        btn_invoke_js2.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                mWebView.loadUrl("javascript:javacalljswith(\"JAVA调用了JS的有参函数\")");            }        });    }    @JavascriptInterface    public void localMethods(String arg) {        Log.i(TAG, "This method is called!");        Toast.makeText(this, "This method is called!", Toast.LENGTH_SHORT).show();    }    private class InsideWebViewClient extends WebViewClient {        @Override        public void onPageFinished(WebView view, String url) {            mWebView.loadUrl("javascript:" + "window.alert('Js injection success')" );            super.onPageFinished(view, url);        }    }}

最后

不懂得地方欢迎私信我,我会在第一时间给予回复,如阅读中发现写错的地方,欢迎纠正。

转载地址:http://jedul.baihongyu.com/

你可能感兴趣的文章
流媒体技术学习笔记之(八)海康、大华IpCamera RTSP地址和格式
查看>>
《剑指offer》-数据流中的中位数
查看>>
当sql报错代码,不允许对表操作的原因
查看>>
php 处理 非法访问
查看>>
Jenkins安装部署
查看>>
15.4. Service-oriented architecture (SOA)
查看>>
Oracle的一些基本索引
查看>>
shell中if语句的格式以及使用
查看>>
SAP Lenoardo Machine Learning
查看>>
5 Ways to Sell SAP S/4 HANA
查看>>
JS编程建议——26:小心if嵌套的思维陷阱
查看>>
Singleton(单例)模式和Double-Checked Locking(双重检查锁定)模式
查看>>
HDOJ 1013 Digital Roots
查看>>
软硬差异定性未来发展 笔电屏幕走在分岔路口
查看>>
Java魔法堂:JVM的运行模式 (转)
查看>>
thinkPHP四种URL访问方式(二)
查看>>
HDOJ 1064Financial Management
查看>>
全局变量声明的规范化(转)
查看>>
统一用户名
查看>>
Xamarin.Android开发实践(七)
查看>>