在WebView控件中,若是页面中调用了javascript脚本console.log 方法,就调用一个Java方法.javascript
在Android的WebView控件中,有一个setChromeClient(WebChromeClient)方法,java
此方法的参数是WebChromeClient对象,经过重载此对象中的onConsoleMessage方法就android
能够达到此目的.看代码:web
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才有的方法,第二个方法是旧版本的.ide
第二个方法已经不推荐使用了,可是在旧版本的android中,仍然须要此方法.因此最好两个方法都实现.性能
默认的实如今某些版本的手机中很差使,onConsoleMessage方法死活不被调用测试
使用WebView的addJavascriptInterface方法:this
// 首先,定一个类,叫什么名称均可以,可是里面的方法名必须与 // 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方法那么详细,好比行号,就无法输出.code
因此,咱们应该在onConsoleMessage好使的时候使用onConsoleMessage,很差使的时候在使用咱们自定义的方式.orm
那么,如何来判断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; } }