Android 关于Tencent vConsole 添加入webView 总结

官方地址:

https://github.com/Tencent/vConsole/blob/dev/doc/tutorial_CN.md

上面文档中提供了两种常见的引入H5工程思路,简单易懂!

今天这篇文章要说明的是,不同于官方文档的接入方式。

先说背景:H5工程方,因框架原因不愿意或者不方便引入,这样就导致问题定位模糊,容易产生相互推诿的情况,那么作为app 客户端的我们又该如何应对呢?

思路:了解官方文档明白,本质就是引入一段js代码。那么为何不通过webView 直接注入。

不考虑兼容性的情况下(4.4以下),通过webVIew.evaluateJavascript的方法就可实现注入js。

实践1:网络cdn 引用 注入。

代码如下:

String injectScript = "(function() {" +

"function loadVConsole() {" +

" if (!window.vConsoleLoaded) {" +

" var script = document.createElement('script');" +

" script.type = 'text/javascript';" +

" script.src = 'https://unpkg.com/vconsole/dist/vconsole.min.js';" +

" script.onload = function() {" +

" window.vConsoleLoaded = true;" +

" if (window.vConsoleLoaded && window.vConsoleInstance == null) {" +

" window.vConsoleInstance = new VConsole();" +

" }" +

" };" +

" document.head.appendChild(script);" +

" }" +

"}" +

"loadVConsole();" + // 调用函数来加载VConsole

"})();";

binding.dwebVIew.evaluateJavascript(injectScript, null);

至此vConsole 就可以使用了。

然后又突发奇想,如果放到本地会不会更快?

所以出现了

实践2:本地assets 文件中的js引用 注入。

try {

if(TextUtils.isEmpty(vConsoleScript)) {

// 读取assets文件夹中的vconsole.min.js文件

InputStream inputStream = getAssets().open("jsbrg/vconsole.min.js");

int size = inputStream.available();

byte\[\] buffer = new bytesize;

inputStream.read(buffer);

inputStream.close();

vConsoleScript = new String(buffer, "UTF-8");

}

// 构造注入到WebView中的JavaScript代码

if(TextUtils.isEmpty(injectScript)) {

injectScript = "(function() {" +

"function loadVConsole() {" +

" if (!window.vConsoleLoaded) {" +

" var script = document.createElement('script');" +

" script.type = 'text/javascript';" +

" script.textContent = '" + escapeJavaScriptString(vConsoleScript) + "';" +

" document.head.appendChild(script);" +

" window.vConsoleLoaded = true;" +

" if (window.vConsoleLoaded && !window.vConsoleInstance) {" +

" window.vConsoleInstance = new VConsole();" +

" }" +

" }" +

"}" +

"loadVConsole();" +

"})();";

}

// 注入JavaScript代码到WebView中

binding.dwebVIew.evaluateJavascript(injectScript, null);

} catch (IOException e) {

e.printStackTrace();

}

其中遇到两个坑:

1、从assets文件夹中读取,注意路径一定得有,否则会io异常

2、上述方法有个关键方法,字符转义方法,加载的字符串无法直接注入,所以没这个方法无法注入成功,如下:

public static String escapeJavaScriptString(String input) {

if (input == null || input.isEmpty()) {

return "";

}

StringBuilder sb = new StringBuilder(input.length());

for (int i = 0; i < input.length(); i++) {

char c = input.charAt(i);

switch © {

case '\':

sb.append("\\");

break;

case ''':

sb.append("\'");

break;

case '"':

sb.append("\"");

break;

case '

':

sb.append("\r");

break;

case '

':

sb.append("

");

break;

case ' ':

sb.append("\f");

break;

case '':

sb.append("\b");

break;

case ' ':

sb.append("\t");

break;

// 对于其他需要转义的字符,如 <, >, &, 也可以在这里添加

// 但通常这些字符在 JavaScript 字符串中不需要转义,除非它们被嵌入到 HTML 中

default:

// 对于 ASCII 范围内的字符,通常不需要转义

// 但对于非打印字符或特殊 Unicode 字符,你可能需要添加额外的逻辑

if ((c >= 0x20 && c <= 0x7E) || Character.isISOControl©) {

sb.append©;

} else {

sb.append©;

}

}

}

return sb.toString();

}

以上就是两种不同官方添加vConsole的方法,本质都是通过安卓 webView的动态注入js方法。

实践2:确实更快一些,个人感觉!免去了网络延时,多了本地处理时间,大家可以对比一下

看到最后,恭喜你获得,踩坑经历大礼包:

注入的时机选择:

1、onPageFinished

2、onPageStarted

3、onProgressChanged

经过我的实践:我这边认为最好的注入时机,这个三个地方都加上,onProgressChanged 方法中进度超过35%时开始注入。由于在注入代码中有添加是否注入过的逻辑,所以不用担心重复注入。

onPageStarted 这里添加是为了能尽可能的快注入成功,可能尽可能多的获取日志。

onPageFinished 这里添加是,前两处注入都失败了,有个保底方案。

看到这里,缺点也非常明显,日志是否能打印全,取决于注入成功的时间。所以会损失部分初始日志,但我测试也是偶发情况。

到此分享结束,我也是迫于无奈才出此下策,有更好的办法,欢迎分享。最后的最后希望大家不会用到这种方法,尽量让前端同学自己添加

相关推荐
HLC++10 小时前
Linux的进程间通信
android·linux·服务器
爱笑鱼14 小时前
Binder(二):AIDL 生成的 Proxy、Stub 和 Parcel 到底在做什么?
android
爱笑鱼14 小时前
Binder(一):一次方法调用,究竟怎样跨进程执行?
android
壮哥_icon15 小时前
【Android 系统开发】使用 BAT 脚本高效自动化管理 /system/priv-app/ 系统应用(安装与卸载)
android·运维·自动化
用户693717500138416 小时前
Claude Code终端日志Token占用实测:一个过滤器砍掉60%-90%
android·前端·后端
蝉蜕日记17 小时前
AccumuPDF高级版 v2.57 | 视图文转换PDF,合并分割压缩
android·智能手机·pdf·生活·软件需求
吐了啊取名字太难17 小时前
美颜系统AI修图本地跑并支持Mac、win、安卓、iOS不卡顿
android·人工智能·windows·数码相机·mac·ai编程
阿pin18 小时前
Android随笔-Retrofit
android·retrofit
想取一个与众不同的名字好难18 小时前
安卓自定义颜色选择器
android
我命由我1234519 小时前
Android 开发问题:java.lang.NoSuchMethodError:No virtual method readAllBytes()
android·java·java-ee·kotlin·android studio·android-studio·android runtime