-
2021-05-26 13:28:30
import android.app.Dialog;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
public class WebViewDialog extends Dialog {
public WebViewDialog(Context context) {
super(context);
setContentView(R.layout.layout_webview);
Window window = getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.type = WindowManager.LayoutParams.TYPE_TOAST;
params.height = WindowManager.LayoutParams.MATCH_PARENT;
params.width = WindowManager.LayoutParams.MATCH_PARENT;
window.setAttributes(params);
mWebView = (WebView) findViewById(R.id.web_view);
mWebView.setWebViewClient(mWebViewClientBase);
/*此处禁用JavaScript,而是在后面onAttachedToWindow事件中再启用JavaScript的支持,同时强制页面刷新
* 这么处理的原因是由于前端同学在开发页面时候,会使用一个自有的JavaScript框架,这个框架会在页面
* 加载完成后,立即获取页面的宽高,但是此时获取到的宽高都是 0 ,因为此时Chrome还没有完成整个页面的Layout
* 因此我们需要在页面完成Layout后再次加载页面才可以,但是如果此处启用JavaScript的支持会导致埋点数据的意外
* 上行,导致双份的埋点问题,因此,此处强制禁用JavaScript
* */
mWebView.getSettings().setJavaScriptEnabled(false);
mWebView.addJavascriptInterface(new JsBridge(),"JsBridge");
}
@Override
public void onAttachedToWindow() {
/*此处我们呼应下面代码中禁用JavaScript的支持的部分代码
* 原因也已经解释的非常详细了
* 但是此处需要注意,就是先reload再次启用JavaScript这个顺序不要乱掉,否则
* 可能还没有调用reload之前,前一个页面已经执行了JavaScript导致页面上面的埋点两次执行。
*
* 关于性能的隐忧,由于我们重新reload了页面,地址链接并没有改变,因此并不会去服务器上面重新获取页面
* 此处的性能隐忧,应该是不存在的
*
* 至于是不是需要手工设置一下Chrome内核的缓存时间,这个在目前的实际实验观察看来,是不需要的。
*
* */
mWebView.reload();
mWebView.getSettings().setJavaScriptEnabled(true);
}
public void showWebView(){
final String strHtml = "" +
"
" +"
" window.JsBridge.jsGetWindowWithHeight(document.documentElement.clientWidth,document.documentElement.clientHeight);" +
" " +
" " +
"";
mWebView.loadData(strHtml,"text/html","UTF-8");
}
public class JsBridge{
@JavascriptInterface
public final void jsGetWindowWithHeight(int aWidth,int aHeight) {
Log.d("jsGetWindowWithHeight","Width=" + aWidth + " Height=" + aHeight);
Toast.makeText(getContext(),"Width=" + aWidth + " Height=" + aHeight,Toast.LENGTH_LONG).show();
}
}
private class WebViewClientBase extends WebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
mHandler.removeCallbacks(mShowRunnable);
mHandler.post(mShowRunnable);
}
}
private final Runnable mShowRunnable = new Runnable() {
@Override
public void run() {
WebViewDialog.this.show();
}
};
private final WebViewClientBase mWebViewClientBase = new WebViewClientBase();
private WebView mWebView;
private static Handler mHandler = new Handler(Looper.getMainLooper());
}
更多相关内容 -
android webview获取网页源代码,js执行前后
2017-07-12 10:29:40webview获取网页源代码分两种,一种是js执行前,一种是js执行后 1.js执行前 调用getHtml即可 public static String getHtml(String path) throws Exception { // 通过网络地址创建URL对象 URL url = new URL(path...webview获取网页源代码分两种,一种是js执行前,一种是js执行后
1.js执行前
调用getHtml即可public static String getHtml(String path) throws Exception { // 通过网络地址创建URL对象 URL url = new URL(path); // 根据URL // 打开连接,URL.openConnection函数会根据URL的类型,返回不同的URLConnection子类的对象,这里URL是一个http,因此实际返回的是HttpURLConnection HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 设定URL的请求类别,有POST、GET 两类 conn.setRequestMethod("GET"); //设置从主机读取数据超时(单位:毫秒) conn.setConnectTimeout(5000); //设置连接主机超时(单位:毫秒) conn.setReadTimeout(5000); // 通过打开的连接读取的输入流,获取html数据 InputStream inStream = conn.getInputStream(); // 得到html的二进制数据 byte[] data = readInputStream(inStream); // 是用指定的字符集解码指定的字节数组构造一个新的字符串 String html = new String(data, "utf-8"); return html; } public static byte[] readInputStream(InputStream inStream) throws Exception { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while ((len = inStream.read(buffer)) != -1) { outStream.write(buffer, 0, len); } inStream.close(); return outStream.toByteArray(); }
2.js执行后
启用jssettings.setJavaScriptEnabled(true);
定义接口private final class InJavaScriptLocalObj { public void showSource(String html2) { html = html2; } }
webview添加自定义接口webView.addJavascriptInterface(new InJavaScriptLocalObj(), "local_obj");
添加webviewClient回调,执行指定jsprivate WebViewClient webViewClient = new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); view.loadUrl("javascript:window.local_obj.showSource('<head>'+" + "document.getElementsByTagName('html')[0].innerHTML+'</head>');"); }
在需要获取网页源代码的地方后去html变量即可 -
Android WebView 调用JS方法获取返回值
2022-01-20 11:29:05一、Android4.4+ 如果你项目的minSdkVersion 为4.4 以上,...webview.evaluateJavascript("javascript:JSMethod()", new ValueCallback<String>() { @Override public void onReceiveValue(String value) {一、Android4.4+
如果你项目的minSdkVersion 为4.4 以上,那么你可以直接通过WebView的evaluateJavascript()方法 拿到JS方法的返回值
webview.evaluateJavascript("javascript:JSMethod()", new ValueCallback<String>() { @Override public void onReceiveValue(String value) { //此处为 js 返回的结果 } }); }
二、Android4.4 以下
minSdkVersion 在4.4以下,那么你就不得不做适配除了以上方法可以调用JS方法,还有一种传统的方法也可以调,那就是通过WebView的loadUrl()。但是该方法不直接返回JS方法的返回值,我们可以使用一些小技巧间接的获取该JS方法的返回值。例如,我们通常是这么调用一个JS的 方法
webView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); webView.loadUrl("javascript:JSMethod('" + userId + "')"); } });
但该JS方法没有添加回调原生的函数时,我们是获取不到该方法的返回值
那么我们就得换一种方式,直接调用JS的alert方法将JS方法的返回值提示给我们,alert出来的message就是我们要获取的返回值。
将上面调用JS方法的地方改一下:
webView.loadUrl("javascript:alert(JSMethod('" + userId + "'))");
拿到JSAlert返回的消息并处理提示框
webview.setWebChromeClient( new WebChromeClient() { @Override public boolean onJsAlert(WebView view, String url, String message, final JsResult result) { Logger.e(message); result.confirm(); return true; } );
这样既能调用到JS方法,也能拿到该JS 方法的返回值,当然如果你加载的这个H5 页面有其他的alert也是会在这里回调的,至于怎么处理就见仁见智了,例如你可以给个flag啊…
注意事项:
1.加载完H5 之后再调用JS方法,所以你的JS方法可以写在onPageFinished里面,而且要在父类方法后面执行。
2.自行处理alert回调时,要执行result.confirm();或JSResult的其他方法告诉H5我处理完了,return true表示我们拦截了系统的alert提示。 -
Android 实测WebView获取页面的post请求参数(form,ajax)
2021-11-27 12:07:29所以可以直接拦截url获得,但是post请求的参数信息存放在body里面,android没有提供方法直接获取,而该网页是其他第三方提供的,不方便修改网页代码来传递参数给android原生这边,所以可以通过js注入的方式来获取。...背景
由于项目需求要获取某些网页的请求参数信息,get请求的参数拼接在url中,所以可以直接拦截url获得,但是post请求的参数信息存放在body里面,android没有提供方法直接获取,而该网页是其他第三方提供的,不方便修改网页代码来传递参数给android原生这边,所以可以通过js注入的方式来获取。
关键步骤
js代码
核心js代码下载jscore
从文件中读取js代码为字符串,便于后面给webview加载public class IOUtils { public static byte[] readFully(InputStream in) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; for (int count; (count = in.read(buffer)) != -1; ) { out.write(buffer, 0, count); } return out.toByteArray(); } }
WebViewClient注入js代码
在页面加载完成回调onPageFinished的时候通过webview.loadUrl()将js代码注入到当前页面
public class InterceptingWebViewClient extends WebViewClient { private Context mContext = null; private WebView mWebView = null; private PostInterceptJavascriptInterface mJSSubmitIntercept; public InterceptingWebViewClient(Context context, WebView webView) { mContext = context; mWebView = webView; mJSSubmitIntercept = new PostInterceptJavascriptInterface(this); mWebView.addJavascriptInterface(mJSSubmitIntercept, "interception"); } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { mNextAjaxRequestContents = null; mNextFormRequestContents = null; view.loadUrl(url); return true; } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); try { String mInterceptHeader = new String(IOUtils.readFully(mContext.getAssets().open("jscore"))); view.loadUrl("javascript:" + mInterceptHeader); }catch (Exception e){ Log.e("zbm", "js注入失败:" + e); } } private PostInterceptJavascriptInterface.FormRequestContents mNextFormRequestContents = null; public void nextMessageIsFormRequest(PostInterceptJavascriptInterface.FormRequestContents formRequestContents) { mNextFormRequestContents = formRequestContents; } private PostInterceptJavascriptInterface.AjaxRequestContents mNextAjaxRequestContents = null; public void nextMessageIsAjaxRequest(PostInterceptJavascriptInterface.AjaxRequestContents ajaxRequestContents) { mNextAjaxRequestContents = ajaxRequestContents; } }
js与android通信桥梁
当页面有post请求时会回调customAjax与customSubmit接口将请求参数传给原生层。
public class PostInterceptJavascriptInterface { private static String mInterceptHeader; private InterceptingWebViewClient mWebViewClient; public PostInterceptJavascriptInterface(InterceptingWebViewClient webViewClient) { mWebViewClient = webViewClient; } public class FormRequestContents { public String method = null; public String json = null; public String enctype = null; public FormRequestContents(String method, String json, String enctype) { this.method = method; this.json = json; this.enctype = enctype; } } public class AjaxRequestContents { public String method = null; public String body = null; public AjaxRequestContents(String method, String body) { this.method = method; this.body = body; } } @JavascriptInterface public void customAjax(final String method, final String body) { mWebViewClient.nextMessageIsAjaxRequest(new AjaxRequestContents(method, body)); } @JavascriptInterface public void customSubmit(String json, String method, String enctype) { mWebViewClient.nextMessageIsFormRequest( new FormRequestContents(method, json, enctype)); } }
-
WebView调用js方法获取返回值的完美解决方案
2021-02-17 09:32:17WebView调用js方法获取返回值的完美解决方案 -
webview获取标签内容
2016-06-13 18:06:36webView执行js代码获取标签内容 -
Android WebView注入JQuery、JS脚本及执行无效的问题解决
2021-06-02 15:20:37在项目中遇到JQuery注入后,执行无效的问题。我们知道必须在网页加载完成后,也就是在onPageFinished()方法被调用...why,i dont know...WebView注入JS的封装JSUtil.javaimport android.app.Activity;import android... -
WebView执行javascript遇到的坑
2016-07-15 16:48:08使用的js代码有问题,webview不兼容该代码。 1) 第一个坎:WebSettings WebSettings webSettings = mWebView.getSettings(); webSettings.setJavaScriptEnabled(true); 2) 第二个坎: 有物 在运行脚本前,要有... -
electron webview iframe执行preload (nodeintegrationinsubframes)
2021-04-15 15:51:47electron 项目,webview页面 的 子iframe页面 加载 preload.js 解决方案: 在主线程 main.js 中 需要打开权限 nodeIntegrationInSubFrames: true 在页面标签中也需要打开权限 nodeintegrationinsubframes main.js ... -
webview 和JS交互且传参
2021-11-25 11:45:37webview 和JS交互且传参 1.native 给JS 传参 1.1 mWebView.loadUrl 这种形式没有返回值,调用js的gotoJS方法。 另外还有重载方法loadUrl (String url, Map<String, String> additionalHttpHeaders),可以添加... -
android webview 加载URL js不执行的解决方法
2021-05-28 08:57:43在使用过程中发现页面的有些js 不执行,下面介绍个人遇到这问题的解决方法及相关知识的记录。一个加载本地html 文件的例子:import android.app.Activity;import android.os.Bundle;import android.webkit.... -
Android WebView详解和调用JS,androidrom开发书籍
2021-11-26 11:18:47//覆盖WebView默认使用第三方或系统默认浏览器打开网页的行为,使网页用WebView打开 mWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String ... -
【踩坑记录】JavaScript 在 iOS WebView 中获取定位信息
2021-06-11 10:58:46百度地图API在iOS中要求承载页面中所有资源(包括但不限于图片、css、js)使用https协议获取,不允许存在任何以http协议请求的资源,否则,在该请求执行后,定位方法将无法成功执行。(安卓无该限制) 具体体现为: ... -
Android WebView详解和调用JS,踩坑了
2022-03-19 22:59:17*/ @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { ...(4)访问的页面中有Javascript,则webview必须设置支持Javascript WebSettin -
Andorid WebView获取JS全局变量或者调用方法的返回值
2021-02-05 00:34:45但是借助该接口,原生java代码,采用webview.loadUrl("javascript:JsFunctionName"),只能做到执行js中的方法,如果想获取js中定义的全局变量,或者获取某个js函数的返回值,这种方式无法做到,webview也没有提供别... -
Html5 webview 模版 ,实现 JS 获取imei , 上传文件功能
2021-06-11 13:27:14// 获取webView 控件 webview = (WebView) findViewById(R.id.webview); // 加上这句话才能使用javascript方法 webview.getSettings().setJavaScriptEnabled(true); webview.loadUrl(... -
Android WebView详解和调用JS,Android事件分发机制收藏这一篇就够了
2022-01-23 12:29:44等都可以实现WebView的使用。 (3)然后就可以在网页: //WebView加载web资源 mWebView.loadUrl(“https://www.baidu.com/”); 实例使用 (1)设置网页顶部加载进度条(判断页面加载过程): WebSettings ... -
Android webview数据获取 webview抓取
2020-03-10 11:02:40总结下 Android下 webview的数据获取、抓取。 先说总结的情况 方法一:给webview setWebViewClient,然后重写shouldInterceptRequest,获取请求参数,自己发起请求,返回WebResourceResponse。 方法二:... -
在WebView中使用JavaScript获取网页内容
2016-08-13 17:30:512. 将java类对象注入到webView的js中(为null时将被忽略),这样就可以通过webView中的js来执行java代码了。 3. 重写WebViewClient的onPageFinished方法,在onPageFinished中加载一段js代码调用本地方法。 ... -
WebView与Javascript交互(相互调用参数、传值)
2020-08-01 22:56:55今天我将全面介绍Android通过WebView与JS交互的全面方式目录1. 交互方式总结Android与JS通过WebView互相调用方法,实际上是:Android去调用JS的代码 JS去调用Android的代码二者沟通的桥梁是WebView对于Android调用JS... -
android webview获取html代码和根据id获取value实例
2021-06-07 10:33:241 前言最近做一个项目,需要webview获取网页中input的内容,把知识整理一下,做个记录,也希望对大家有所帮助。2 获取html内容2.1 初始化webviewwebview.getSettings().setJavaScriptEnabled(true);webview.... -
webview获取网页title
2017-12-22 05:44:04今天做项目的时候,老大让我把之前做的webview打开网页的功能修改一下,说是要动态的获取网页的标题,然后显示在我们自己app的标题栏上,然后我就屁颠屁颠的跑去看webview的源码,看看有没有获取标题这个方法。... -
关于android webview读取js全局变量或者函数返回值
2021-05-27 03:07:15但是借助该接口,原生java代码,采用webview.loadUrl("javascript: JsFunctionName"),只能做到执行js中的方法,如果想获取js中定义的全局变量,或者获取某个js函数的返回值,这种方式无法做到,webview也没有提供别... -
webview调用js方法
2018-07-12 12:35:53* 调用js方法 由于webview中调用js需要拼接成字符串比较麻烦,所以简单的封装了一下 * * @param strs 第一个参数是js方法名字,其余任意个参数为传递给js的参数 */ public void callJs(Object... strs) { ... -
Android中通过Java获取Webview加载内容
2021-06-02 16:54:27有时候我们需要在加载webview时,获取加载完成的内容,当然,WebView也是有可能包含javascript。通过以下操作,我们是可以获取到WebView加载的内容。1、自定义一个内部类,获取WebView加载的内容class Handler {... -
Android WebView的使用方法及与JS 相互调用
2021-06-06 01:46:44Android WebView的使用方法及与JS 相互调用1、添加网络权限2、WebSettings 对访问页面进行设置。WebView mWebView = new WebView(this);WebSettings webSettings = mWebView .getSettings();//支持获取手势焦点,... -
Android(五十七):WebView - 获取网页logo和标题、监听页面滚动、刷新页面、两端交互
2021-12-24 16:54:38// 允许执行js脚本 // 必须,参数一为供前端使用的对象Value(仅暴露的),参数二为供前端使用的对象Key _webView.AddJavascriptInterface(new JavaScriptMethod(this), "Android"); _webView.LoadUrl(... -
Webview与Javascript
2021-03-04 11:55:220x01 WebView 概述 WebView 是 Android 的一个控件,用于在应用程序中展示 Web 网页 Google 的官方解释为 A View that displays web pages. This class is the basis upon which you can roll your own web browser...