0

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


While Developing a webapp-native-hybrid especially for an Android-Device I was happy to be able to merge the JavaScript-console with the ordinary LogCat. But what a pity: there is a console.debug which results in MessageLevel.INFO and no console.verbose() at all (error get thrown).

1
  • I wonder what the "TIP" message level is for. Could it be for suggestions from the webkit on how to improve the content's performance, similar to those nags Firefox shows in the console when onscroll effects are used? Couldn't find any info, so as it stands, I also decided to map it to Log.v in my Android WebView, just like you did. Commented Jun 18, 2024 at 16:00

1 Answer 1

2

To solve this I would extend the functionality of the console with a simple (and really ugly and instable) adapter:

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

This adapter provides the logging functions while adding a prefix (DEBUG)# or (VERBOSE)# to the message given as parameter and call error() from original console object. Hopefully this will be the least used Level, so that's the place where to check the incoming messages for the prefix. The wished logging level of LogCat gets chosen by the extracted prefix:

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

I tried to manipulate the console functions by prototype, but at this time I'm not this familiar to get a working result right now. For my purposes it's enough and eventually someone other can use this crap.

If someone would provide me the few lines of prototyping I would be glad, and I hope that next time I need something like this I will be able to do it myself ;)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.