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

    }

原文地址:https://www.cnblogs.com/renhui/p/9330844.html

时间: 2024-10-10 04:55:28

Android WebView 加载超长 JS 数据的相关文章

Android WebView加载Chromium动态库的过程分析

Chromium动态库的体积比较大,有27M左右,其中程序段和数据段分别占据25.65M和1.35M.如果按照通常方式加载Chromium动态库,那么当有N个正在运行的App使用WebView时,系统需要为Chromium动态库分配的内存为(25.65 + N x 1.35)M.这是非常可观的.为此,Android使用了特殊的方式加载Chromium动态库.本文接下来就详细分析这种特殊的加载方式. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注! 为什么当有

Android WebView加载本地html并实现Java与JS交互

最近做的一个项目中,用到自定义地图,将自定义地图转换成html页面,现在需要做的是如何将本地的html加载到android中,并可以实现交互. 相关讲解: 其实webview加载资源的速度并不慢,但是如果资源多了,当然就很慢.图片.css .js .html这些资源每个大概需要10-200ms ,一般都是30ms就ok了.不过webview是必须等到全部资源都完成加载,才会进行渲染的,所以加载的速度很重要!从Google上我们了解到,webview加载页面的顺序是:先加载html,然后从里面解析

Android Webview 加载外部html时选择加载本地的js,css等资源文件

在使用WebView加载网页的时候,有一些固定的资源文件如js的jquery包,css,图片等资源会比较大,如果直接从网络加载会导致页面加载的比较慢,而且会消耗比较多的流量.所以这些文件应该放在assets里面同app打包. 要解决这个问题需要用到API 11(HONEYCOMB)提供的shouldInterceptRequest(WebView view, String url) 函数来加载本地资源.在API 21又将这个方法弃用了,是重载一个新的shouldInterceptRequest,

转:Android Webview 加载外部html时选择加载本地的js,css等资源文件

原文地址:http://m.blog.csdn.net/blog/qduningning/43196819 在使用WebView加载网页的时候,有一些固定的资源文件如js的jquery包,css,图片等资源会比较大,如果直接从网络加载会导致页面加载的比较慢,而且会消耗比较多的流量.所以这些文件应该放在assets里面同app打包. 要解决这个问题需要用到API 11(HONEYCOMB)提供的shouldInterceptRequest(WebView view, String url) 函数来

对于android WebView加载不出Html5网页的解决方法

之前碰到一个问题,就是用webview去加载一个H5的页面,但是发现加载出现一片空白,但是我把我的链接放到浏览器里却又是可以的,找了会,被我老大叫过去搞别的了,然后被我老大找出来了,就是因为对某些标签的不支持,加上: settings.setDomStorageEnabled(true); 然后网页就显示出来了.

android webview 加载图片过大

我们app 图文详情 页面如果加载图片的话,有时会出现超出屏幕的情况(上下左右都可以滚动),重新进这个页面有时又不会 webview加这个设置后,情况好很多 webV_content_pic.getSettings() .setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); // 就是这句

Android webView 加载网页时,使用本地图片替换网页内的图片

============问题描述============ RT,本质目的是阻止网页图片加载,将图片放在本地,然后在app中替换,以加快反应速度. 以前提过这个问题,没能解决,因为3.0以上才提供了替换网页资源的接口(WebResourceResponse),3.0以下没有专门的接口,想过使用get将网页取下来存为String然后替换,却发现不是所有的网页都能使用get取到(很多页面都报异常,包括百度中的某些链接),研究过一段时间,认为不能实现,放弃了. 今天突然发现一款游戏,叫巴哈姆特之怒,惊讶

Android-报错总结之一:WebView加载本地JS

今天帮朋友做了一个apk,内容全是用html5做的,然后把整个文件夹(包括js.cs.image等等)全部一股脑的塞到assets目录下,然后在代码里通过webview调用loadUrl("file:///android_asset/xxx.html"),js支持也都加上了, settings.setJavaScriptEnabled(true);,本来满打满算的运行起来一点问题没有,结果报了个比较蛋疼的错,报错的内容是Cannot read property 'giftDoctorU

[Android学习系列2]用webview写界面,加载本地js,js,html文件

以jquery mobile为例 1.在android界面拖入一个webview,然后添加一个internet权限 <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <uses-permission android:name="android.permission.INTERNET"/> <application ........