java js注入,WebView与Javascript交互及JS的注入

29b64f6724ae

本篇目录

前言

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

一、Java 调用 JS 中函数

1.添加权限(这里使用资源目录下写好的html文件)

2.webView配置

...

// 省略掉findView..webview

mWebView.getSettings().setJavaScriptEnabled(true);

3.利用webView的loadUrl()方法调用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调用的方法。

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

...

@JavascriptInterface

public 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导致的问题或可能出现的问题

注入js可能会导致加载的html5页面总是一直在加载中,加载很慢或干脆加载不出来,这个问题不是针对所有的html5可能在某些网页上会遇到这个问题;

注入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注入遇到的问题部分,自行加入。

1. web.html文件

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

function javacalljs(){

document.getElementById("content").innerHTML = "
JAVA调用了JS的无参函数";

}

function javacalljswith(arg){

document.getElementById("content").innerHTML = ("
"+arg);

}

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);

}

}

}

最后

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值