Я пытаюсь вызвать некоторые javascript функции, сидящие в html страница работает внутри android webview. Довольно просто то, что код пытается сделать ниже — из приложения android, вызвать функцию javascript с тестовым сообщением, которое inturn вызывает функцию java обратно в приложении android, которое отображает тестовое сообщение через toast.

Переменная javascript выглядит следующим образом:

function testEcho(message){
     window.JSInterface.doEchoTest(message);
}

Из WebView я безуспешно пытался назвать javascript следующими способами:

myWebView.loadUrl("javascript:testEcho(Hello World!)");
mWebView.loadUrl("javascript:(function () { "   "testEcho(Hello World!);"   "})()");

Я действительно включил javascript. Если вы хотите, чтобы экземпляры имели свои собственные массивы, создайте их в функции, а не в прототипе. WebView

myWebView.getSettings().setJavaScriptEnabled(true);
// register class containing methods to be exposed to JavaScript
myWebView.addJavascriptInterface(myJSInterface, "JSInterface"); 

И вот Java может привести к долгосрочному кэшированию файла , в результате чего ваша ссылка не будет обновляться при нажатии новых версий. Ссылка на файл по коммит-хешу или тегу делает ссылку уникальной для версии.

public class JSInterface{

private WebView mAppView;
public JSInterface  (WebView appView) {
        this.mAppView = appView;
    }

    public void doEchoTest(String echo){
        Toast toast = Toast.makeText(mAppView.getContext(), echo, Toast.LENGTH_SHORT);
        toast.show();
    }
}

я потратил много времени на поиски, чтобы посмотреть, что Я могу делать неправильно. Все примеры, которые я нашел, используют этот подход. Кто-нибудь видит здесь что-то не так?

Мы только что выпустили Есть несколько других внешних javascript файлов, на которые ссылается & Amp ;, используемых в html, могут ли они быть проблемой?

Я понял, в чем проблема: пропущенные кавычки в параметре testEcho (). Вот как я получил вызов для работы:

myWebView.loadUrl("javascript:testEcho('Hello World!')");

Начиная с kitkat, используйте метод loadJavascript вместо loadUrl для вызова функций javascript, как показано ниже:

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        webView.evaluateJavascript("enable();", null);
    } else {
        webView.loadUrl("javascript:enable();");
    }
public void run(final String scriptSrc) { 
        webView.post(new Runnable() {
            @Override
            public void run() { 
                webView.loadUrl("javascript:"   scriptSrc); 
            }
        }); 
    }

Я создал хорошую оболочку для вызова методов JavaScript ;, она также показывает ошибки JavaScript в журнале:

private void callJavaScript(String methodName, Object...params){
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append("javascript:try{");
    stringBuilder.append(methodName);
    stringBuilder.append("(");
    for (int i = 0; i < params.length; i  ) {
        Object param = params[i];
        if(param instanceof String){
            stringBuilder.append("'");
            stringBuilder.append(param.toString().replace("'", "\'"));
            stringBuilder.append("'");
        }
        if(i < params.length - 1){
            stringBuilder.append(",");
        }
    }
    stringBuilder.append(")}catch(error){Android.onError(error.message);}");
    webView.loadUrl(stringBuilder.toString());
}

Вы должны добавить это тоже:

private class WebViewInterface{

    @JavascriptInterface
    public void onError(String error){
        throw new Error(error);
    }
}

И добавить этот интерфейс в ваше веб-представление:

webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new WebViewInterface(), "AndroidErrorReporter");

Да, у вас есть синтаксическая ошибка. Если вы хотите получать ошибки Javascript и операторы печати в logcat, вы должны реализовать метод onConsoleMessage(ConsoleMessage cm) в вашем WebChromeClient. Он дает полные трассировки стека, такие как веб-консоль (элемент Inspect). Вот метод.

public boolean onConsoleMessage(ConsoleMessage cm) 
    {
        Log.d("Message", cm.message()   " -- From line "
                               cm.lineNumber()   " of "
                               cm.sourceId() );
        return true;
    }

После реализации вы получите ваши ошибки Javascript и операторы печати (console.log) на вашем logcat.

Изменение ответа @Ilya_Gazman

    private void callJavaScript(WebView view, String methodName, Object...params){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("javascript:try{");
        stringBuilder.append(methodName);
        stringBuilder.append("(");
        String separator = "";
        for (Object param : params) {               
            stringBuilder.append(separator);
            separator = ",";
            if(param instanceof String){
                stringBuilder.append("'");
            }
                stringBuilder.append(param.toString().replace("'", "\'"));
            if(param instanceof String){
                stringBuilder.append("'");
            }

        }
        stringBuilder.append(")}catch(error){console.error(error.message);}");
        final String call = stringBuilder.toString();
        Log.i(TAG, "callJavaScript: call=" call);


        view.loadUrl(call);
    }

‘ISO8601’ == ‘Ymd \ TH: i: sO’

callJavaScript(mBrowser, "alert", "abc", "def");
//javascript:try{alert('abc','def')}catch(error){console.error(error.message);}
callJavaScript(mBrowser, "alert", 1, true, "abc");
//javascript:try{alert(1,true,'abc')}catch(error){console.error(error.message);}

Обратите внимание, что объекты не будут переданы правильно — но вы можете сериализовать их перед передачей в качестве аргумента.

Кроме того, я изменил место ошибки. Я перенаправил ее в журнал консоли, который можно прослушать:

    webView.setWebChromeClient(new CustomWebChromeClient());

и клиентом

class CustomWebChromeClient extends WebChromeClient {
    private static final String TAG = "CustomWebChromeClient";

    @Override
    public boolean onConsoleMessage(ConsoleMessage cm) {
        Log.d(TAG, String.format("%s @ %d: %s", cm.message(),
                cm.lineNumber(), cm.sourceId()));
        return true;
    }
}