android webview onconsolemessage,WebView控件中的onConsoleMessage方法不被调用

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运行了,就添加一个标记,表示默认的实现是好使的.

@Override

public 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;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值