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 的位置和粗细比较相符,于是去控制 ...
随机推荐
- Visual Studio Installer 设置属性简介
1. 创建安装项目 2.创建项目完成之后,具体各类操作和文件的添加需要自行设置 2.1文件系统 针对文件安装位置,内容进行设置.包括文件,项目输出,程序集 2.2.文件类型(不常用) 设置文件后缀名 ...
- vue实例的生命周期
Vue实例的生命周期也就是这个实例从出生到死亡的过程,所以我在文档原图上把这个周期大致分为创建过程 | 运行过程 | 销毁过程三个阶段,不同结果或又分为一些小的阶段 在第一个阶段,创建阶段,会完成Vu ...
- python中的深浅copy
https://www.cnblogs.com/Eva-J/p/5534037.html 转自Eva_J 分析的特别好
- 用Java代码通过JDBC连接Hiveserver2
1.在终端启动hiveserver2#hiveserver2 2.使用beeline连接hive另外打开一个终端,输入如下命令(xavierdb必须是已经存在的数据库)#beeline -u jdbc ...
- java 日志体系(三)log4j从入门到详解
java 日志体系(三)log4j从入门到详解 一.Log4j 简介 在应用程序中添加日志记录总的来说基于三个目的: 监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析工作: 跟踪代 ...
- AX_DataSource
for (custInvoiceJourLocal = custInvoiceJour_ds.getFirst(true) ? custInvoiceJour_ds.getFirst(true) : ...
- PackageManagerService 学习记录 基于7.1.1源码
参考: http://blog.csdn.net/innost/article/details/47253179 http://blog.csdn.net/gaugamela/article/deta ...
- PCL-CMAKELIST书写格式
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)//cmake最小版本 find_package(PCL 1.3 REQUIRED COMPONENTS ...
- springboot 使用mysql(mybatis)
添加mysql依赖项 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifac ...
- kettle连接oracle报错oracle.i18n.text.converter.CharacterConverter.OGS.getInstance(I)Loracle/i18n/text/converter/CharacterConverter
问题背景1:需要将一张excel中的数据导入到数据库中,并且还有关联转换和去重的处理问题,且此excel表不是固定的,需要写一个脚本 当新的excel拿来的时候,可以直接导入即可.所以我想用kettl ...