在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; } }