javascript - WebView 代码在 Android 4.4.2 (API 19) 模拟器上生成 Uncaught TypeError 和 Uncaught ReferenceError 错误

标签 javascript android webview android-emulator mathjax

在 Android 4.4.2 KitKat (API 19) 模拟器上运行时,我的代码出现问题...

当我在 Android 4.3 (API 18) 模拟器上模拟我的项目时,它正常工作并使用 MathJax 创建数学表达式:

Image of emulator

但是当我使用 Android 4.4.2 模拟器时,应用程序无法正常运行:

Image of emulator

这是我的项目代码:

package com.testes.testesapp;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends Activity implements View.OnClickListener {

    private int exampleIndex = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        WebView webView = (WebView) findViewById(R.id.webview);
        webView.getSettings().setJavaScriptEnabled(true);
        //webView.getSettings().setBuiltInZoomControls(true);
        webView.loadDataWithBaseURL("http://test", "<script type='text/x-mathjax-config'>"
                              + "MathJax.Hub.Config({ " 
                              + "showMathMenu: false, "
                              + "jax: ['input/TeX','output/HTML-CSS'], " // output/SVG
                              + "extensions: ['tex2jax.js','toMathML.js'], " 
                              + "TeX: { extensions: ['AMSmath.js','AMSsymbols.js',"
                              + "'noErrors.js','noUndefined.js'] }, "
                              // + "'SVG' : { blacker: 30, "
                              // + "styles: { path: { 'shape-rendering': 'crispEdges' } } } "
                              + "});</script>"
                              + "<script type='text/javascript' "
                              + "src='file:///android_asset/MathJax/MathJax.js'"
                              + "></script>"
                              + "<span id='math'></span>","text/html","utf-8","");
        EditText edit = (EditText) findViewById(R.id.edit);
        edit.setBackgroundColor(Color.LTGRAY);
        edit.setTextColor(Color.BLACK);
        edit.setText("");
        Button btnShow = (Button) findViewById(R.id.btnShow);
        btnShow.setOnClickListener(this);
        Button btnClear = (Button) findViewById(R.id.btnClear);
        btnClear.setOnClickListener(this);
        Button btnExample = (Button) findViewById(R.id.btnExample);
        btnExample.setOnClickListener(this);
    }

    private String doubleEscapeTeX(String s) {
        String t="";
        for (int i=0; i < s.length(); i++) {
            if (s.charAt(i) == '\'') t += '\\';
            if (s.charAt(i) != '\n') t += s.charAt(i);
            if (s.charAt(i) == '\\') t += "\\";
        }
        return t;
    }

    private String getExample(int index) {
        return getResources().getStringArray(R.array.tex_examples)[index];
    }

    public void onClick(View v) {
        if (v == findViewById(R.id.btnShow)) {
            WebView webView = (WebView) findViewById(R.id.webview);
            EditText edit = (EditText) findViewById(R.id.edit);
            webView.loadUrl("javascript:document.getElementById('math').innerHTML='\\\\["
                            + doubleEscapeTeX(edit.getText().toString()) + "\\\\]';");
            webView.loadUrl("javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);");
        }
        else if (v == findViewById(R.id.btnClear)) {
            WebView webView = (WebView) findViewById(R.id.webview);
            EditText edit = (EditText) findViewById(R.id.edit);
            edit.setText("");
            webView.loadUrl("javascript:document.getElementById('math').innerHTML='';");
        }
        else if (v == findViewById(R.id.btnExample)) {
            WebView webView = (WebView) findViewById(R.id.webview);
            EditText edit = (EditText) findViewById(R.id.edit);
            edit.setText(getExample(exampleIndex++));
            if (exampleIndex > getResources().getStringArray(R.array.tex_examples).length - 1) 
                exampleIndex=0;
            webView.loadUrl("javascript:document.getElementById('math').innerHTML='\\\\["
                            + doubleEscapeTeX(edit.getText().toString()) + "\\\\]';");
            webView.loadUrl("javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);");
        }
    }

}

当我按下“Example”或“Show”按钮时,LogCat 发出错误:

I/chromium(1254): [INFO:CONSOLE(1)] "Uncaught TypeError: Cannot set property 'innerHTML' of null", source: http://test/ (1)
I/chromium(1254): [INFO:CONSOLE(1)] "Uncaught ReferenceError: MathJax is not defined", source: http://test/ (1)

我不知道如何解决这个问题,希望有人能帮助解决这个问题。谢谢。

最佳答案

我也遇到了这个问题。

这是我的解决方案:

  1. 将您的基本 URL 从 "http://test" 更改为 "http://test/"
  2. 将此代码 webView.loadUrl(..) 更改为 webView.evaluateJavascript(..);。特别是对于我们想要加载 innerHTML 的代码。不要忘记添加注释 @TargetApi(Build.VERSION_CODES.KITKAT) 因为它仅适用于 Android 4.4 及更高版本
  3. 永远不要将 webView.loadWithBaseUrl(..)webView.loadUrl(..) 放在同一个进程中。因为如果 webView.loadUrl(..)webView.loadWithBaseUrl(..) 完成之前加载,它会引发错误,如 OP 所述。

对于数字 3,您的代码已经符合此要求(因为在您的代码中,webView.loadUrl(..) 执行已经与 webView.loadWithBaseUrl(..)< 分开 通过使用 OnClick 事件。所以,不要关注它。

但是如果您的应用需要在一个事件中加载它们,请考虑使用以下代码将它们分开: `

private void initiateWebView(){

    webViewEquationDisplay.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);

            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
                loadUrlKitKat(equationSymbolFinal+equationToBeDisplayedFinal);
            }
            else{
                webViewEquationDisplay.loadUrl("javascript:document.getElementById('math').innerHTML='<font color=\"yellow\">`"+equationToBeDisplayedFinal+"`</font>';");
            }

            webViewEquationDisplay.loadUrl("javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);");
        }
    });

    final String mathJaxOfflineUrl = "file:///android_asset/MathJax/MathJax.js";            
    webViewEquationDisplay.loadDataWithBaseURL("http://bar/", "<script type='text/x-mathjax-config'>"
            +"MathJax.Hub.Config({ " 
                +"showMathMenu: false, "
                +"jax: ['input/AsciiMath','output/HTML-CSS'], "
                +"extensions: ['asciimath2jax.js'], " 
                +"AsciiMath: { fixphi: true, useMathMLspacing: true, displaystyle: false, decimalsign: \".\" }, "
              +"});</script>"
            +"<script type='text/javascript' "
              +"src='"+mathJaxOfflineUrl+"'"
              +"></script><span id='math'></span>","text/html","utf-8","");
}


@TargetApi(Build.VERSION_CODES.KITKAT)
private void loadUrlKitKat(String param){
    webViewEquationDisplay.evaluateJavascript("javascript:document.getElementById('math').innerHTML='<font color=\"#97FD97\">`"+param+"`</font>';",null);
}

`

祝你好运

关于javascript - WebView 代码在 Android 4.4.2 (API 19) 模拟器上生成 Uncaught TypeError 和 Uncaught ReferenceError 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25173360/

相关文章:

java - 使用 Javascript 从 WebView 调用 Activity 的方法

javascript - 使用 GitHub API 获取呈现的 html wiki 页面

javascript - 在 JavaScript 中将事件监听器绑定(bind)到特定日期和时间之间的提交表单

javascript - 如何手动检查 YUI radio "button"

java - GATT 特性不改变值

java - firebase 数据库或我的 ListView 在前几项之后复制数据

javascript - WebView中来自OnClick(来自HTML中的按钮)的Activity中的触发方法

javascript - 如何编写正确的正则表达式以便 JSLint 进行验证?

java - 我如何知道用户在我的 Android 应用程序上使用 firebase-ui 时是否已经创建了帐户?

java - 我怎样才能有一个 ListView 项目,其中只有一个 WebView ?