博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WebView控件中的onConsoleMessage方法不被调用
阅读量:6316 次
发布时间:2019-06-22

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

hot3.png

1.目的

在WebView控件中,如果页面中调用了javascript脚本console.log 方法,就调用一个Java方法.

 

2.默认实现方法

在Android的WebView控件中,有一个setChromeClient(WebChromeClient)方法,

此方法的参数是WebChromeClient对象,通过重载此对象中的onConsoleMessage方法就

可以达到此目的.看代码:

WebView webView = new WebView();webView.setWebChromeClient(new DefaultWebChromeClient);// 以上代码放在在Activity或则Fragment中的onCreate方法中private class DefualtWebChromeClient extends WebChromeClient {    @Override    public boolean onConsoleMessage(ConsoleMessage consoleMessage) {        String message = consoleMessage.message();        int lineNumber = consoleMessage.lineNumber();        String sourceID = consoleMessage.sourceId();        String messageLevel = consoleMessage.message();        Log.i("[WebView]", String.format("[%s] sourceID: %s lineNumber: %n message: %s",                messageLevel, sourceID, lineNumber, message));        return super.onConsoleMessage(consoleMessage);    }    @Override    public void onConsoleMessage(String message, int lineNumber, String sourceID) {        Log.i("[WebView]", String.format("sourceID: %s lineNumber: %n message: %s", sourceID,                lineNumber, message));        super.onConsoleMessage(message, lineNumber, sourceID);    }}

第一个方法onConsoleMessage(ConsoleMessage consoleMessage)是新版本的android才有的方法,第二个方法是旧版本的.

第二个方法已经不推荐使用了,但是在旧版本的android中,仍然需要此方法.所以最好两个方法都实现.

 

3.问题

默认的实现在某些版本的手机中不好使,onConsoleMessage方法死活不被调用

 

4.解决方案

使用WebView的addJavascriptInterface方法:

// 首先,定一个类,叫什么名称都可以,但是里面的方法名必须与// Javascript的console中的方法名对应private class Console{    private static final String TAG="[WebView]";    public void log(String msg){        Log.i(TAG,msg);    }	// 还可以添加其他的方法,比如: warn,assert等等}// 然后,为WebView添加对应的接口webView.addJavascriptInterface(new Console, "console");

 

这个解决方案有一个不好的地方,就是输出的内容没有onConsoleMessage方法那么详细,比如行号,就没法输出.

所以,我们应该在onConsoleMessage好使的时候使用onConsoleMessage,不好使的时候在使用我们自定义的方式.

那么,如何来判断onConsoleMessage是否好使呢? 我们可以在程序初始化的时候,先在WebView中运行一下console.log,

如果onConsoleMessage运行了,就添加一个标记,表示默认的实现是好使的.

@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {    // 这些代码也可以放到onCreate方法中	    this.webView = (WebView) layout.findViewById(R.id.webview);    WebSettings webSettings = webView.getSettings();    webSettings.setJavaScriptEnabled(true);        // Set WebChromeClient    WebChromeClient webChromeClient = new TestConsoleMessageWebChromeClient();	// 先执行console.log,测试是否调用了onConsoleMessage    webView.loadUrl("javascript:console.log('testConsoleMessage')");	    if (((TestConsoleMessageWebChromeClient)webChromeClient).isConsoleMessageOK()){	    // 这里额外使用了一个新的类 TestConsoleMessageWebChromeClient		// 如果不适用TestConsoleMessageWebChromeClient,就需要在		// DefaultWebChromeClient中添加标记字段 consoleMessageOK,		// 这样如果方法onConsoleMessage好使,那么每次都给consoleMessageOK赋值,		// 这个有些多余,也影响性能.        webChromeClient = new DefualtWebChromeClient();    }else{	    // onConsoleMessage不好使,就使用这种方式,第二个参数值必须是"console"        webView.addJavascriptInterface(new Console(), "console");    }        webView.loadUrl("http://www.baidu.com");    return super.onCreateView(inflater, container, savedInstanceState);}// 当默认的onConsoleMessage不好使的时候使用的类private class Console {    private static final String TAG = "[WebView]";    public void log(String msg) {        Log.i(TAG, msg);    }	// 这里还可以添加其他方法console对象中有的方法,比如 assert}// 默认private class DefualtWebChromeClient extends WebChromeClient {    @Override    public boolean onConsoleMessage(ConsoleMessage consoleMessage) {        String message = consoleMessage.message();        int lineNumber = consoleMessage.lineNumber();        String sourceID = consoleMessage.sourceId();        String messageLevel = consoleMessage.message();        Log.i("[WebView]", String.format("[%s] sourceID: %s lineNumber: %n message: %s",                messageLevel, sourceID, lineNumber, message));        return super.onConsoleMessage(consoleMessage);    }    @Override    public void onConsoleMessage(String message, int lineNumber, String sourceID) {        Log.i("[WebView]", String.format("sourceID: %s lineNumber: %n message: %s", sourceID,                lineNumber, message));        super.onConsoleMessage(message, lineNumber, sourceID);    }}// 用于测试onConsoleMessage是否调用的类private class TestConsoleMessageWebChromeClient extends WebChromeClient {    private boolean consoleMessageOK = false;    @Override    public boolean onConsoleMessage(ConsoleMessage consoleMessage) {        this.consoleMessageOK = true;        return super.onConsoleMessage(consoleMessage);    }    @Override    public void onConsoleMessage(String message, int lineNumber, String sourceID) {        this.consoleMessageOK = true;        super.onConsoleMessage(message, lineNumber, sourceID);    }    public boolean isConsoleMessageOK() {        return this.consoleMessageOK;    }}

转载于:https://my.oschina.net/xmlspyspring/blog/126045

你可能感兴趣的文章
SpringMVC深度探险(一) —— SpringMVC前传
查看>>
vmstat
查看>>
福克斯:悲观?乐观?就看你与世界怎么互动
查看>>
MySQL导出数据文件
查看>>
第四章——SQLServer2008-2012资源及性能监控(1)
查看>>
hadoop中的序列化与Writable接口
查看>>
微信企业号
查看>>
【转载】Android dip,px,pt,sp 的区别
查看>>
Hark的数据结构与算法练习之圈排序
查看>>
使用 Spring 2.5 TestContext 测试框架
查看>>
打豪车应用:uber详细攻略(附100元优惠码)
查看>>
CSS3系列教程:HSL 和HSL
查看>>
关于论文检索的几点知识
查看>>
解析:使用easyui的form提交表单,在IE下出现类似附件下载时提示是否保存的现象...
查看>>
算法-数组中重复的数字
查看>>
Linux下samba的安装与配置
查看>>
分析Cocos2d-x横版ACT手游源 1、登录
查看>>
Redis入门很简单之六【Jedis常见操作】
查看>>
Java中的Enum的使用与分析
查看>>
WebView之2
查看>>