2

I'm having a problem with my code when running on a Android 4.4.2 KitKat (API 19) emulator...

When I emulate my project on a Android 4.3 (API 18) emulator, it works normally and creates the mathematical expressions with MathJax:

Image of emulator

But when I use a Android 4.4.2 emulator, the app don't work correctly:

Image of emulator

Here is the code of my project:

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

}

When I press the "Example" or the "Show" button, LogCat emits the errors:

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)

I have no idea how to fix this problem, and would like somebody's help to solve this. Thanks.

3 Answers 3

6

I got this problem too.

Here is my solution:

  1. change your base URL from "http://test" to "http://test/"
  2. change this code webView.loadUrl(..) to webView.evaluateJavascript(..);. Especially for code where we want to load innerHTML. Don't forget to add anotation @TargetApi(Build.VERSION_CODES.KITKAT) because it's only for Android 4.4 and above
  3. never put webView.loadWithBaseUrl(..) in the same process with webView.loadUrl(..). Because If webView.loadUrl(..) was loaded before webView.loadWithBaseUrl(..) finished, it will raise error as OP stated above.

For number 3, your codes is already conform with this (because in your codes, webView.loadUrl(..) execution was already separated with webView.loadWithBaseUrl(..) by using OnClick event. So, don't pay attention to it.

But if your apps need to load them at one event, consider to separate them by using this code: `

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

`

good luck

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

2 Comments

This is the best answer for the KitKat problem! Thanks, Dimas
what is "equationSymbolFinal" mentioned in the code?
1

I had the same problem when I moved different javascript functions out of the main page to an separate .js file. For some reason, Android can't find externally-loaded JavaScript webview functions from Java - only the ones in the main page. Once I moved the function back from the JS file, it immediately started working.

Try making a "proxy" function like this directly inside the main HTML:

function proxy() {
    call_some_other_function_from_JS_file();
}

This worked for me. I'm sure there must be a way to get find these functions, because I didn't have this problem on iOS. Someone please comment if you know a better way.

1 Comment

Figure out this problem, solved it. using:- If the app targets LOLLIPOP or above the default web view behaviour is to completely deny mixed content. As mobile connect requires the use of HTTP during header enrichment we need a more relaxed security setting. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { webView.getSettings().setMixedContentMode(WebSettings.MIXED_‌CONTENT_COMPATIBILIT‌Y_MODE); }
0

webview.evaluateJavascript("javascript:document.getElementById('math').innerHTML='"+doubleEscapeTeX(questn)+"';",null);

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

This is the sollution for api 19 or above

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.