javascript - 如何在 WebView 中扩展 JavaScript 控制台(以匹配 ConsoleMessage.MessageLevel)

标签 javascript android logging webview android-webview

Debugging Web Apps :

Android's WebKit does not implement all of the console APIs available in other desktop browsers. You can, however, use the basic text logging functions:

console.log(String)
console.info(String)
console.warn(String)
console.error(String)

Other console functions don't raise errors, but might not behave the same as what you expect from other web browsers.


android.webkit.ConsoleMessage.MessageLevel :

ConsoleMessage.MessageLevel DEBUG
ConsoleMessage.MessageLevel ERROR
ConsoleMessage.MessageLevel LOG
ConsoleMessage.MessageLevel TIP
ConsoleMessage.MessageLevel WARNING

<小时/>

在开发专门针对 Android 设备的 webapp-native-hybrid 时,我很高兴能够将 JavaScript 控制台与普通 LogCat 合并。但遗憾的是:有一个 console.debug 会导致 MessageLevel.INFO,而根本没有 console.verbose() (抛出错误)。

最佳答案

为了解决这个问题,我将使用一个简单(而且非常丑陋且不稳定)的适配器来扩展控制台的功能:

var c = window.console;
window.console = {
    debug:   function(message) { c.error("(DEBUG)#" + message); },
    verbose: function(message) { c.error("(VERBOSE)#" + message); },
    error:   function(message) { c.error(message); },
    warn:    function(message) { c.warn(message); },
    log:     function(message) { c.log(message); },
    info:    function(message) { c.info(message); }
};

for (i in c) {
    try {
        window.console[c[i]]();
    } catch(error) {
        if(verbose) console.verbose("Funktion nicht implementiert: " + c[i]);
        window.console[c[i]] = function(arguments) {
            if(debug) console.debug("Aufruf nicht implementierter Funktion: " + this);
            var funcDefArray = ("" + this).split(" ");
            c[funcDefArray[1]](arguments);
        };
    }
}

此适配器提供日志记录功能,同时向作为参数给出的消息添加前缀 (DEBUG)#(VERBOSE)# 并调用 error() 来自原始控制台对象。希望这将是最少使用的级别,以便在此处检查传入消息的前缀。 LogCat 所需的日志记录级别由提取的前缀选择:

public class CustomWebChromeClient extends WebChromeClient {
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
    String tag = TAG_JS;
    StringBuffer message = new StringBuffer(consoleMessage.message());

    MessageLevel lvl = consoleMessage.messageLevel();
    if (lvl == MessageLevel.ERROR) {
        int i = message.indexOf(")#");
        if(i > 0 && i < 8) {
            String realLevel = message.substring(1, i);
            message.replace(0, i+2, "");
            if("DEBUG".equals(realLevel)) lvl = MessageLevel.DEBUG;
            else if("VERBOSE".equals(realLevel)) lvl = MessageLevel.TIP;
            else tag += " (" + realLevel + ")";
        } else {
            String source = consoleMessage.sourceId();
            source = source.substring(source.indexOf("/js/") + 1);
            message.append(source);  
            message.append('(').append(consoleMessage.lineNumber()).append(')');
            message.append(" –> ");
        }
    }

    message.append(consoleMessage.message());
    switch (lvl) {
    case ERROR:
        Log.e(tag, message.toString());
        break;
    case WARNING:
        Log.w(tag, message.toString());
        break;
    case LOG:
        Log.i(tag, message.toString());
        break;
    case DEBUG:
        Log.d(tag, message.toString());
        break;
    case TIP:
        Log.v(tag, message.toString());
        break;
    default:
        Log.println(Log.ASSERT, tag, message.toString());
        break;
    }
    return true;
}
}

我尝试通过原型(prototype)操作控制台功能,但目前我不太熟悉如何立即获得工作结果。就我的目的而言,这已经足够了,最终其他人也可以使用这个废话。

如果有人能给我提供几行原型(prototype),我会很高兴,我希望下次我需要这样的东西时我能够自己做;)

关于javascript - 如何在 WebView 中扩展 JavaScript 控制台(以匹配 ConsoleMessage.MessageLevel),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13222006/

相关文章:

javascript - 不确定为什么 Javascript eventListener 没有链接到 SVG 元素?

javascript - 带箭头移动 Canvas 框

ruby-on-rails - Rails 不记录请求

python - 如何防止记录 pyspark 'answer received' 和 'command to send' 消息

java - 如何动态移动布局?

android - 你如何在Android上记录一个int?

javascript - ng-repeat 完成事件

javascript - 如何在页面完成加载后启用禁用的输入字段 - Vuejs

android - BottomNavigationView 在 Snackbar 出现时移动

android - 尝试在自定义对话框中使用 getIntent() 会出现错误。解决此错误的解决方案?