博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android WebView 加载超长 JS 数据
阅读量:6613 次
发布时间:2019-06-24

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

在之前的文章里面,我总结过WebView如何与网页交互,也就是Java如何和JS交互 —— 。 基于这篇文章,我们基本上能完成绝大部分交互的逻辑。但是,因为业务需要,最近加载的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. Parametersscript    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
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(); } } }

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

你可能感兴趣的文章
k sum(lintcode)
查看>>
Android 控件属性
查看>>
React-Native 之 GD (十六)首页筛选功能
查看>>
SSISDB5:使用TSQL脚本执行Package
查看>>
【转】UIColor对颜色的自定义
查看>>
asp.net后台进程做定时任务
查看>>
Ural_1671. Anansi's Cobweb(并查集)
查看>>
给vs2012换肤
查看>>
java接口中多继承的问题
查看>>
索引笔记《二》确定需要建立索引的列
查看>>
libjpeg的问题
查看>>
Ubuntu+Apache+PHP+Mysql环境搭建(完整版)
查看>>
深度学习笔记之CNN(卷积神经网络)基础
查看>>
Hadoop 添加删除数据节点(datanode)
查看>>
ext的window如何隐藏水平滚动条
查看>>
71.8. Run level shell script to start Oracle 10g services on RedHat Enterprise Linux (RHAS 4)
查看>>
SAP QM Transfer of Inspection Stock
查看>>
全新视觉| 数治省市:SAP大数据构想一切可能
查看>>
ORACLE expdp备份与ORA-31693、ORA-02354、ORA-02149
查看>>
DBMS_STATS.GATHER_TABLE_STATS
查看>>