1

I have an application published in google play targetting API version 16 to 26 (minSdkVersion 16, targetSdkVersion 26). I got a few low rating reviews because "webview informations not appearing" on android 8 or higher. (not all devices, some)

This apps propose is to show LaTEX as mathematic formulas using MathJax.

I've tested my app using android studio emulators (all API versions) and there were no errors but low ratings are still rolling in.

this is my custom webiew:

public class MathView extends WebView {

String textColor = "#000000";
String backgroundColor = "#ffffff";

public Boolean loaded = false;

public String tag = "white";
public String text = "";

public MathView(Context context, AttributeSet attrs){
    super(context, attrs);
    this.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
    String tag = "white";
    if(attrs != null)
         tag = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "tag");

    initView(context,tag);
}

public void displayText(String text){
    this.text = text;
    loadMath();
}

private String getTemplate(){
    String template = "<!DOCTYPE html>\n" +
            "<html>\n" +
            "<head>\n" +
            "<style>\n" +
            "        img {\n" +
            "            max-width: 90% !important;\n" +
            "            height: auto!important;\n" +
            "        }\n" +
            "        .mjx-chtml {\n" +
            "            font-size: 100% !important;\n" +
            "        }\n" +
            "    </style>\n" +
            "    <script src=\"file:///android_asset/mathview/MathJax.js?config=TeX-MML-AM_CHTML\"></script>\n" +
            "    <script src=\"file:///android_asset/mathview/extensions/img.js?config=TeX-MML-AM_CHTML\"></script>\n" +
            "    <script>\n" +
            "        MathJax.Hub.Config({\n" +
            "            \"HTML-CSS\": {\n" +
            "                linebreaks: {\n" +
            "                    automatic: !0\n" +
            "                }\n" +
            "            },\n" +
            "            CommonHTML: {\n" +
            "                linebreaks: {\n" +
            "                    automatic: true\n" +
            "                }\n" +
            "            },\n" +
            "            SVG: {\n" +
            "                linebreaks: {\n" +
            "                    automatic: true\n" +
            "                }\n" +
            "            },\n" +
            "            displayAlign: \"left\"\n" +
            "        });\n" +
            "    </script>\n" +
            "</head>\n" +
            "\n" +
            "<body style=\"background:"+this.backgroundColor+";color:"+this.textColor+";overflow:hidden;font-family:serif;\">\n" +
            this.text +
            "</body>\n" +
            "\n" +
            "</html>";

    return template;
}


public void setValues(float[] values){
    // Do stuff calculating
}
private void initView(Context context, @Nullable String tag){

    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    inflater.inflate(R.layout.custom_webview, this);
    this.getSettings().setJavaScriptEnabled(true);
    getSettings().setAllowFileAccess(true);
    getSettings().setDisplayZoomControls(false);
    getSettings().setBuiltInZoomControls(false);
    getSettings().setSupportZoom(false);
    getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);

    if(tag != null)
        this.tag = tag;
    loadMath();
}

private void loadMath(){
    if(!text.equals("")){
        if(tag.equals("white")){
            this.loadDataWithBaseURL("null",this.getTemplate(),"text/html","UTF-8","about:blank");
        }
        else if(tag.equals("purple")){
            textColor = "#ffffff";
            backgroundColor = "#da4b71";
            this.loadDataWithBaseURL("null",this.getTemplate(),"text/html","UTF-8","about:blank");
        }
        else if(tag.equals("purple_dark")){
            textColor = "#ffffff";
            backgroundColor = "#bb4061";
            this.loadDataWithBaseURL("null",this.getTemplate(),"text/html","UTF-8","about:blank");
        }
        else if(tag.equals("gray")){
            backgroundColor = "#f1f1f1";
            this.loadDataWithBaseURL("null",this.getTemplate(),"text/html","UTF-8","about:blank");
        }
    }

}


public void passValue(final String value){
    this.text = value;
    loadMath();
}
public void updateValue(final String value){
    this.text = value;
    loadMath();
}

public void setBackground(String color){
    this.backgroundColor = color;
}
public void setTextColor(String color){
    this.textColor = color;
}
}

This is my xml that will be associated with this custom webview inside and activity:

<packagename.views.MathView
    android:id="@+id/titleMathView"
    android:scrollbars="none"
    android:tag="white"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    />

and i use webview inside of an activity using this codes:

MathView titleMathView titleMathView = (MathView) findViewById(R.id.titleMathView);//this resource exists inside xml file
titleMathView.setWebChromeClient(new chromeClient());
titleMathView.displayText("\\(\\frac{1}{2}\\)"); //Now math must be displayed

this is my chromClient Class:

private ProgressDialog questionsLoading;
private class chromeClient extends WebChromeClient {
            Runnable hideLoadingRunnable = new Runnable() {
                @Override
                public void run() {
                    questionsLoading.dismiss();
                }
            };
            Runnable showLoadingRunnable = new Runnable() {
                @Override
                public void run() {
                    questionsLoading = ProgressDialog.show(QuizActivity.this, "",
                            "Loading questions...", true);
                    final Handler handler = new Handler();
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            if(questionsLoading != null)
                                if(questionsLoading.isShowing())
                                    hideLoadingRunnable.run();
                        }
                    }, 6000);
                }
            };
            private chromeClient(){
                if(questionsLoading == null)
                    showLoadingRunnable.run();
            }
            @Override
            public void onProgressChanged(WebView view, int progress){//not working
                if(progress == 100) {
                    if(questionsLoading != null)
                        hideLoadingRunnable.run();
                }
            }

}

This is the problematic display screenshot: (one user kindly emailed this to me)

Problematicc screenshot

This is what must displayed:

enter image description here

This is a list of devices that faced the problem (this list is base on reviews in google play, i can't reproduce problem using emmulators):

  • Device: Pixel 3 XL (crosshatch) -> OS: Android 9
  • Device: Pixel XL (marlin) -> OS: Android 9
  • Device: Galaxy Tab A (2017) (gta2swifi) -> OS: Android 8.1
  • Device: Galaxy J7 (j7y17lte) -> OS: Android 8.1
  • Device: Galaxy S10+ (beyond2) -> OS: Android 9
Mehdi Nazari
  • 113
  • 2
  • 13
  • can you show what result do you accept? – BlackBlind Mar 27 '19 at 07:26
  • @BlackBlind the whole project propose is to display LaTEX as Math formulas. I simplified the codes for posting it in stackoverflow. I now edited the question and put all of my codes in. please see my update on custom webiew class. – Mehdi Nazari Mar 27 '19 at 07:38
  • @BlackBlind I added two screenshots to the question in order to describe the problem better. – Mehdi Nazari Mar 27 '19 at 07:59
  • Do you have a list of problem devices? – Morrison Chang Mar 27 '19 at 08:44
  • @MorrisonChang I updated the question and added a list of devices based on "Not Displaying Webview" reviews. – Mehdi Nazari Mar 27 '19 at 09:05
  • Can you reproduce the issue if you fire up an emulator with one of the problem devices? Does the issue consistently happen? – JensV Mar 27 '19 at 09:07
  • If you are able to reproduce the issue, follow [this guide](https://developers.google.com/web/tools/chrome-devtools/remote-debugging/) to debug the webview – JensV Mar 27 '19 at 09:08
  • @JensV, unfortunately, I can't reproduce the problem anywhere, I tried emulators with exact os version and device but no luck, webview shows up without problem. in lots of real devices (not same device, same os) webview display is also ok. – Mehdi Nazari Mar 27 '19 at 09:28
  • Perhaps it happens when chrome is outdated? I don't really have any other ideas – JensV Mar 27 '19 at 10:49
  • @JensV if that, i can't do anything about it. i'm trying updating everything to android.x, maybe this helps. – Mehdi Nazari Mar 27 '19 at 13:03
  • 1
    Can you show us the xml layout file as well? Perhaps it's related to https://stackoverflow.com/questions/1981507/why-does-android-webview-display-a-black-screen – JensV Mar 27 '19 at 13:19
  • @JensV I updated the question for xml part. it's bad luck that i can't reproduce the problem, if i could i would try changing match_parent and wrap_content values. – Mehdi Nazari Mar 27 '19 at 13:54
  • 1
    It seems that your container for the webview has a fixed height set, so I would try to use match_parent for both layout attributes. Perhaps some implementations of the webview behave differently with the layouting. Good luck to you – JensV Mar 27 '19 at 13:57
  • @JensV this webview is inside a container with minHeight set. i must use wrap_content because the height may change per text. – Mehdi Nazari Mar 27 '19 at 15:15
  • Perhaps set the minHeight on the webview itself? – JensV Mar 27 '19 at 15:30
  • @JensV you were right when you said "implementations of the webview behave differently with the layouting". finally i could manage to reproduce the problem. i upgraded to android.x API and then i used android Q emulator, then there was the black webview problem. also height=math_parent on webview fixed the problem. i will update the question after checking everything – Mehdi Nazari Mar 27 '19 at 16:12

1 Answers1

1

Thanks to comments, problem fixed easily.

I was not able to reproduce the problem in any emulator or actual devices. after trying lots of different things i decided to upgrade the app to AndroidX API version.

after changing compileSdkVersion to 28 (AndroidX API), problem showed itself on emulators with android 8.1 or higher.

problem was with using android:layout_height="wrap_content" on webview in xml.

after changing it to android:layout_height="match_parent" webview showed information almost fine.

xml of webview is now like this:

<packagename.views.MathView
    android:id="@+id/titleMathView"
    android:scrollbars="none"
    android:tag="white"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

the problem was related to this topic:

Why does Android WebView display a black screen?

but after changing height to match_parent, sometimes webview was too long with lots of extra spaces at the bottom.

i needed that wrap_content part but i could not use it because it cause black webview bug in anroid 8.1 or higher.

to fix this issue i used a javascript interface to change height of webview base on its content.

if you have same problem with match_parent webviews you can read the fixture in this page:

https://stackoverflow.com/a/25187094/2202171

Mehdi Nazari
  • 113
  • 2
  • 13
  • I am having the same issue. however, I don't have control for the webview. How do I change the layout if is on xamarin forms? – Pxaml Jun 19 '19 at 03:18