Android WebView 加载超长 JS 数据
在之前的文章里面,我总结过WebView如何与网页交互,也就是Java如何和JS交互 —— Android WebView 总结 —— Java和JavaScript交互。 基于这篇文章,我们基本上能完成绝大部分交互的逻辑。但是,因为业务需要,最近加载的JS都是超长的数据,但测试发现在Android 16及以下的手机上,能正常使用,但是在17 及以上的手机上,发现JS没有执行。
这是因为,WebView在Android 17及以后对之前的WebView存在的安全问题做了调整。那怎么办呢?答:使用 evaluateJavaScript 方法。
这个方法不仅能执行JS,还可以获取到返回数据,下面是针对这个方法的原文说明:
Asynchronously evaluates JavaScript in the context of the currently displayed page. If non-null, |resultCallback| will be invoked with any result returned from that execution. This method must be called on the UI thread and the callback will be made on the UI thread. Parameters
script the JavaScript to execute.
resultCallback A callback to be invoked when the script execution completes with the result of the execution (if any). May be null if no notificaion of the result is required.
那么Android 17之前的该怎么办?目前的解决方案是通过java反射机制!
在android.webkit包中有个BrowserFrame私有类,该类中有个Native方法:
public native String stringByEvaluatingJavaScriptFromString(String script)
使用步骤
1.扩展WebView添加方法,并使用反射实现。
2.将布局文件中的WebView修改为自定义的WebView
3.使用新的WebView调用方法,执行js方法获取返回值
实现后的自定义WebView调用方法代码如下:
public String stringByEvaluatingJavaScriptFromString(String script) {
try {
//由webview取到webviewcore
Field field_webviewcore = WebView.class.getDeclaredField("mWebViewCore");
field_webviewcore.setAccessible(true);
Object obj_webviewcore = field_webviewcore.get(this);
//由webviewcore取到BrowserFrame
Field field_BrowserFrame = obj_webviewcore.getClass().getDeclaredField("mBrowserFrame");
field_BrowserFrame.setAccessible(true);
Object obj_frame = field_BrowserFrame.get(obj_webviewcore);
//获取BrowserFrame对象的stringByEvaluatingJavaScriptFromString方法
Method method_stringByEvaluatingJavaScriptFromString = obj_frame.getClass().getMethod("stringByEvaluatingJavaScriptFromString", String.class);
//执行stringByEvaluatingJavaScriptFromString方法
Object obj_value = method_stringByEvaluatingJavaScriptFromString.invoke(obj_frame, script);
//返回执行结果
return String.valueOf(obj_value);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
当然,还有更简单的方法,那就是使用腾讯X5内核的WebView提供的evaluateJavaScript,在他们的WebView里面,针对这个问题已经做好的处理。下面是他们的SDK里面的相关代码,在这里做一下展示:
public void evaluateJavascript(String var1, ValueCallback<String> var2) {
if (this.e) {
try {
View var3 = this.f.getView();
Method var4 = com.tencent.smtt.utils.q.a(var3, "evaluateJavascript", new Class[]{String.class, android.webkit.ValueCallback.class});
var4.setAccessible(true);
var4.invoke(this.f.getView(), var1, var2);
} catch (Exception var7) {
var7.printStackTrace();
this.loadUrl(var1);
}
} else if (VERSION.SDK_INT >= 19) {
try {
Class var8 = Class.forName("android.webkit.WebView");
Class[] var9 = new Class[]{String.class, android.webkit.ValueCallback.class};
Method var5 = var8.getDeclaredMethod("evaluateJavascript", var9);
var5.setAccessible(true);
var5.invoke(this.g, var1, var2);
} catch (Exception var6) {
var6.printStackTrace();
}
}
}
Android WebView 加载超长 JS 数据的更多相关文章
- Android WebView加载本地html并实现Java与JS交互
最近做的一个项目中,用到自定义地图,将自定义地图转换成html页面,现在需要做的是如何将本地的html加载到android中,并可以实现交互. 相关讲解: 其实webview加载资源的速度并不慢,但是 ...
- 转:Android Webview 加载外部html时选择加载本地的js,css等资源文件
原文地址:http://m.blog.csdn.net/blog/qduningning/43196819 在使用WebView加载网页的时候,有一些固定的资源文件如js的jquery包,css,图片 ...
- Android WebView 加载富文本内容
WebView加载数据的方式有两种: 1. webView.loadUrl(data);//加载url 2. webView.loadDataWithBaseURL(null,data, " ...
- android webview 加载本地html 实现 与 java 之间的相互响应
1.布局 <?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:androi ...
- Webview加载本地js、图片的方法
在项目开发中经常会将比较大的js.图片.css等放到app中,而html放服务器,这样在使用时流量较少,加载也比都放服务器上快,其实方法也比较多,网上搜了很久都没结果. 一种是获取服务器返回的html ...
- Android WebView 加载网页
通过Android 中 WebView 控件加载HTML5 页面,这是实现Android 混合开发的基础. 选择加载的网页可以是本地,也可用使远程的.需要添加访问互联网的权限:<uses-per ...
- Android webView加载图片显示过大的问题
webview的基本使用流程这里我就不重复说明了,本篇针对的是文章详情加载完成后出现的情况,这里我们使用的方法是:通过js脚本,重置img标签中图片的宽度和高度. 使用步骤: 1.此方法需要使用js, ...
- android webview加载网络连接
webview = (WebView) findViewById(R.id.webview); WebSettings webSettings = webview.getSettings(); //设 ...
- Android WebView加载Html右边空白问题的解决方案
用WebView显示Html时,右边会出现一条空白区,如下图所示: 最开始的时候,认为是网页本身的空白. 后来发现网页本身无问题,且这个空白区是跟Scroll Bar 的位置和粗细比较相符,于是去控制 ...
随机推荐
- Google弃用HttpClient 而推荐使用HttpURLConnection的原因
因为兼容性问题,谷歌不愿意维护HttpClient,而使用HttpURLConnection HttpURLConnection的API包小而简便,更适合安卓 HttpURLConnection能够提 ...
- Redis:MySQL算老几?
原创: 码农翻身刘欣 前言:上一篇<MySQL:缓存算什么东西?>里挖了一个坑,也有很多人说没看过瘾,今天接着写,把坑填上,不过得把视角换一下,让Redis上台发言. 我知道MySQL看我 ...
- ORA-15137: cluster in rolling patch
oracle 12.1.0.2,给diskgroup加盘的时候报错ORA-15137: cluster in rolling patch 确认两节点补丁相同 crsctl query crs soft ...
- position在IE下的问题
盒子设置position:absolute;后,子盒子的浮动可以不做清除浮动处理,同样,使用fixed,子盒子也不需要做清除浮动的处理 在IE7下(据说IE6也不行),盒子设置overflow:hid ...
- VNC 分辨率修改
正确的: vncserver -geometry 1280x1024 错误的: vncserver -geometry 1280*1024
- [精华][推荐]CAS SSO单点登录服务端客户端实例
1.修改server.xml文件,如下: 注意: 这里使用的是https的认证方式,需要将这个配置放开,并做如下修改: <Connector port="8443" prot ...
- 线程池ThreadPoolExecutor源码分析
在阿里编程规约中关于线程池强制了两点,如下: [强制]线程资源必须通过线程池提供,不允许在应用中自行显式创建线程.说明:使用线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销,解决资源 ...
- 格式代码出现两次oracle
报ORA-01810:格式代码出现两次 原因是Java中的年月日和Oracle中的年月日表示形式不一样 oracle用MI来代表分钟,而不是java中的mm
- springBoot 使用拦截器 入坑
近期使用SpringBoot 其中用到了拦截器 结果我的静态资源被全部拦截了,让我导致了好久才搞好: 看下图项目结构: 问题描述:上图划红框的资源都被拦截器给拦截了,搞得项目中不能访问:解决问题就是在 ...
- 20175316盛茂淞 2018-2019-2 《Java程序设计》第9周学习总结
20175316盛茂淞 2018-2019-2 <Java程序设计>第9周学习总结 教材学习内容总结 下载安装MySQL数据库管理系统. 学习<Java程序设计>第十一章MyS ...