-1

After showing my splash activity and redirecting to the next activity, after the next activity is shown it crashes. I have tried to delete splash screens drawable image, but it didn't help. I've also tried logging to see where it crashes and I saw that it creates the next activity, loads the WebView into it and after onDestroy() of the SplashActivity it crashes. A really notable thing here is that IT ONLY CRASHES ON ANDROID API LESS THAN 28 AND ON 28 AND HIGHER IT WORKS FINE. Here is my splash activity:

package io.mediaworks.android.controllers;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.google.android.material.snackbar.Snackbar;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import io.mediaworks.android.App;
import io.mediaworks.android.BuildConfig;
import io.mediaworks.android.R;
import io.mediaworks.android.controllers.articles.ArticlesActivity;
import io.mediaworks.android.notifications.NotificationPresenter;
import io.mediaworks.android.notifications.fcm.TopicsRepository;
import io.mediaworks.android.request.RequestModel;
import io.mediaworks.android.request.model.ArticleSearchResult;
import io.mediaworks.android.request.model.Language;
import io.mediaworks.android.request.model.MenuItem;
import io.mediaworks.android.request.model.MenuType;
import io.mediaworks.android.request.model.Options;
import io.mediaworks.android.request.model.Settings;
import io.mediaworks.android.request.model.Topic;
import io.mediaworks.android.utils.Constants;
import io.mediaworks.android.utils.LanguageManager;

public class SplashActivity extends BaseActivity implements Response.Listener<Settings>, Response.ErrorListener {

    private static final String TAG = "SplashActivity";
    private View view;
    private boolean offlineMode = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate");
        setContentView(view = new View(this));
        loadContent();
    }

    private void loadContent() {
        new RequestModel<>(SplashActivity.this, Request.Method.GET, BuildConfig.BASE_URL + "getSettings", Settings.class, SplashActivity.this, SplashActivity.this);
    }

    @Override
    public void onResponse(Settings settings) {
        App.INSTANCE.setSettings(settings);

        // Should select language
        if (settings.getSelectedLanguage() == null && settings.options.multilanguage) {
            selectLanguage();
        } else {
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    nextStep();
                }
            }, 1000);
        }
        offlineMode = false;
    }

    private void selectLanguage() {
        new AlertDialog.Builder(this).setItems(App.INSTANCE.settings.getLanguageList(), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                LanguageManager.getInstance(SplashActivity.this).selectLanguage(App.INSTANCE.settings.languages[which].code);
                TopicsRepository.getInstance().setTopics();
                nextStep();
            }
        }).setCancelable(false).show();
    }

    @SuppressLint("CommitPrefEdits")
    @Override
    public void onErrorResponse(VolleyError error) {
        offlineMode = true;
        if(!App.INSTANCE.isPodcast() && !App.INSTANCE.isHanzaMedia() && !App.INSTANCE.isBanatSoft()) {
            Snackbar.make(view, this.getString(R.string.error_network_connection), Snackbar.LENGTH_INDEFINITE)
                .setAction(this.getString(R.string.retry), view -> {
                    loadContent();
                }).show();
            }
        else {
            Settings settings = new Settings();
            if(App.INSTANCE.isPodcast())
                settings = podcastOfflineModeSettings();
            else if(App.INSTANCE.isHanzaMedia())
                settings = hanzaMediaOfflineModeSettings();
            else if(App.INSTANCE.isBanatSoft())
                settings = banatSoftOfflineModeSettings();

            SharedPreferences sharedPreferences =
                    PreferenceManager.getDefaultSharedPreferences(App.INSTANCE);
            sharedPreferences.edit().putBoolean(Constants.PREF_KEY_OFFLINE_MODE, offlineMode).apply();

            LanguageManager languageManager = LanguageManager.getInstance(this);
            languageManager.selectLanguage(settings.languages[0].code);
            languageManager.applyLanguage();
            onResponse(settings);
        }
    }

    private void nextStep() {
        LanguageManager languageManager = LanguageManager.getInstance(this);
        languageManager.selectLanguage(App.INSTANCE.settings.languages[0].code);
        languageManager.applyLanguage();

        // Check if from notification
        if (NotificationPresenter.isFromNotification(getIntent().getExtras())) {
            startIntent(NotificationPresenter.getNotificationIntent(this, getIntent().getExtras()));
        }

        // Check deep link
        else if (getIntent().getData() != null && getIntent().getData().isHierarchical()
                && !TextUtils.isEmpty(getIntent().getDataString())) {

            Uri parse = Uri.parse(getIntent().getDataString());
            String param = parse.getQueryParameter("param");
            if (param != null && !TextUtils.isEmpty(param)) {
                try {
                    startIntent(ArticlesActivity.getIntent(this, Integer.parseInt(param), null));
                } catch (Exception e) {
                    e.printStackTrace();
                    startIntent(BrowserActivity.getIntent(this, getIntent().getData().toString()));
                }
            } else {
                final String url = getIntent().getData().toString();

                if(url.equals("http://podcast.rs")){
                    Intent main = new Intent(this,HomeActivity.class);
                    main.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(main);
                    finish();
                    return;
                }
                new RequestModel<ArticleSearchResult>(this, Request.Method.POST, BuildConfig.BASE_URL + "getArticleId", ArticleSearchResult.class, new Response.Listener<ArticleSearchResult>() {

                    @Override
                    public void onResponse(ArticleSearchResult response) {
                        if (response.found) {
                            startIntent(ArticlesActivity.getIntent(SplashActivity.this, response.articleId));
                        } else {
                            startIntent(BrowserActivity.getIntent(SplashActivity.this, url));
                        }
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        startIntent(BrowserActivity.getIntent(SplashActivity.this, url));
                    }
                }) {
                    @Override
                    protected Map<String, String> getParams() {
                        Map<String, String> params = super.getParams();
                        if (params == null) {
                            params = new HashMap<>();
                        }
                        params.put("url", url);
                        return params;
                    }
                };
            }
        }else{
            startIntent(new Intent(this, HomeActivity.class));
        }

    }

    private void startIntent(Intent intent) {
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
        finish();
    }

    private boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager
                = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        assert connectivityManager != null;
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null;
    }

    @Override
    protected void onDestroy() {
        Log.d(TAG, "onDestroy");
        super.onDestroy();
    }

    private Settings hanzaMediaOfflineModeSettings() {
        Settings settings = new Settings();

        settings.languages = new Language[1];
        settings.languages[0] = new Language();
        settings.languages[0].code = "hr";
        settings.languages[0].id = 1;
        settings.languages[0].name = "Croatian";

        settings.selectLanguage(settings.languages[0].code);

        settings.languages[0].leftMenus = new MenuItem[1];
        settings.languages[0].leftMenus[0] = new MenuItem();
        settings.languages[0].leftMenus[0].id = 8;
        settings.languages[0].leftMenus[0].title = "Sačuvani članci";
        settings.languages[0].leftMenus[0].sort = 8;
        settings.languages[0].leftMenus[0].type = MenuType.my_content;
        settings.languages[0].leftMenus[0].url = null;
        settings.languages[0].leftMenus[0].icon = null;
        settings.languages[0].leftMenus[0].rightMenu = new MenuItem[0];

        settings.languages[0].topMenus = new MenuItem[0];

        settings.languages[0].topics = new Topic[0];

        settings.options = new Options();
        settings.options.disableComments = false;
        settings.options.loadArticleFromUrl = false;
        settings.options.multilanguage = false;
        settings.options.showArticleZoom = false;
        settings.options.showSearchButton = false;
        settings.options.showSelectAllTopics = false;
        settings.options.has_bottom = false;

        settings.webViewCss = null;

        return settings;
    }

    private Settings banatSoftOfflineModeSettings() {
        Settings settings = new Settings();

        settings.languages = new Language[1];
        settings.languages[0] = new Language();
        settings.languages[0].code = "ro";
        settings.languages[0].id = 2;
        settings.languages[0].name = "Romania";

        settings.selectLanguage(settings.languages[0].code);

        settings.languages[0].leftMenus = new MenuItem[1];
        settings.languages[0].leftMenus[0] = new MenuItem();
        settings.languages[0].leftMenus[0].id = 8;
        settings.languages[0].leftMenus[0].title = "Conținutul meu";
        settings.languages[0].leftMenus[0].sort = 7;
        settings.languages[0].leftMenus[0].type = MenuType.my_content;
        settings.languages[0].leftMenus[0].url = null;
        settings.languages[0].leftMenus[0].icon = "ic_download";
        settings.languages[0].leftMenus[0].rightMenu = new MenuItem[0];

        settings.languages[0].topMenus = new MenuItem[0];

        settings.languages[0].topics = new Topic[0];

        settings.options = new Options();
        settings.options.disableComments = false;
        settings.options.loadArticleFromUrl = false;
        settings.options.multilanguage = false;
        settings.options.showArticleZoom = false;
        settings.options.showSearchButton = false;
        settings.options.showSelectAllTopics = false;
        settings.options.has_bottom = false;

        settings.webViewCss = null;

        return settings;
    }

    private Settings podcastOfflineModeSettings() {
        Settings settings = new Settings();

        settings.languages = new Language[1];
        settings.languages[0] = new Language();
        settings.languages[0].code = "sr";
        settings.languages[0].id = 1;
        settings.languages[0].name = "Serbian";

        settings.selectLanguage(settings.languages[0].code);

        settings.languages[0].leftMenus = new MenuItem[1];
        settings.languages[0].leftMenus[0] = new MenuItem();
        settings.languages[0].leftMenus[0].id = 46;
        settings.languages[0].leftMenus[0].title = "Offline";
        settings.languages[0].leftMenus[0].sort = 4;
        settings.languages[0].leftMenus[0].type = MenuType.podcasts;
        settings.languages[0].leftMenus[0].url = null;
        settings.languages[0].leftMenus[0].icon = "ic_download";
        settings.languages[0].leftMenus[0].rightMenu = new MenuItem[0];

        settings.languages[0].topMenus = new MenuItem[0];

        settings.languages[0].topics = new Topic[0];

        settings.options = new Options();
        settings.options.disableComments = false;
        settings.options.loadArticleFromUrl = false;
        settings.options.multilanguage = false;
        settings.options.showArticleZoom = false;
        settings.options.showSearchButton = false;
        settings.options.showSelectAllTopics = false;
        settings.options.has_bottom = false;

        settings.webViewCss = "div#cookie-notice {\r\ndisplay: none;\r\n}\r\nfooter#site-footer {\r\ndisplay: none;\r\n}\r\ndiv#secondline-themes-header-position {\r\n    display: none;\r\n}";

        return settings;
    }

}

And here is the exception I get:

W/System.err: java.lang.RuntimeException: Canvas: trying to draw too large(108712800bytes) bitmap.
W/System.err:     at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:229)
        at android.view.RecordingCanvas.drawBitmap(RecordingCanvas.java:78)
        at org.chromium.android_webview.JavaBrowserViewRendererHelper.drawBitmapIntoCanvas(JavaBrowserViewRendererHelper.java:50)
        at org.chromium.android_webview.AwContents.nativeOnDraw(Native Method)
        at org.chromium.android_webview.AwContents.access$5100(AwContents.java:103)
W/System.err:     at org.chromium.android_webview.AwContents$AwViewMethodsImpl.onDraw(AwContents.java:3086)
        at com.android.webview.chromium.WebViewChromium.onDraw(WebViewChromium.java:28365)
        at android.webkit.WebView.onDraw(WebView.java:2790)
        at android.view.View.draw(View.java:19123)
        at android.view.View.updateDisplayListIfDirty(View.java:18073)
        at android.view.View.draw(View.java:18851)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
        at android.view.View.draw(View.java:19126)
        at androidx.core.widget.NestedScrollView.draw(NestedScrollView.java:1998)
W/System.err:     at android.view.View.updateDisplayListIfDirty(View.java:18073)
        at android.view.View.draw(View.java:18851)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
        at android.view.View.draw(View.java:19126)
        at android.view.View.updateDisplayListIfDirty(View.java:18073)
        at android.view.View.draw(View.java:18851)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
        at android.view.View.updateDisplayListIfDirty(View.java:18064)
        at android.view.View.draw(View.java:18851)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
W/System.err:     at android.view.View.updateDisplayListIfDirty(View.java:18064)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
        at android.view.View.updateDisplayListIfDirty(View.java:18032)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
        at android.view.View.updateDisplayListIfDirty(View.java:18032)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
        at android.view.View.updateDisplayListIfDirty(View.java:18032)
W/System.err:     at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
        at android.view.View.updateDisplayListIfDirty(View.java:18032)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
W/System.err:     at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
        at android.view.View.updateDisplayListIfDirty(View.java:18032)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
        at android.view.View.updateDisplayListIfDirty(View.java:18032)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
        at android.view.View.updateDisplayListIfDirty(View.java:18032)
W/System.err:     at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
W/System.err:     at android.view.View.updateDisplayListIfDirty(View.java:18032)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
W/System.err:     at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
        at android.view.View.updateDisplayListIfDirty(View.java:18032)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
        at android.view.View.updateDisplayListIfDirty(View.java:18032)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
W/System.err:     at android.view.View.updateDisplayListIfDirty(View.java:18032)
        at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:643)
        at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:649)
        at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:757)
        at android.view.ViewRootImpl.draw(ViewRootImpl.java:2980)
        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2794)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2347)
W/System.err:     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1386)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6733)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
        at android.view.Choreographer.doCallbacks(Choreographer.java:723)
        at android.view.Choreographer.doFrame(Choreographer.java:658)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
A/chromium: [FATAL:jni_android.cc(243)] Please include Java exception stack in crash report

Any help is appreciated.

Zoe
  • 27,060
  • 21
  • 118
  • 148

1 Answers1

-1

I had solved the problem by setting the android:hardwareAccelerated="false" in my AndroidManifest file, and for faster and smoother image rendering I've changed it to true programmatically in my base activity if the Android version is higher than 27. I Hope I helped someone :)

UPDATE Sorry for not updating the answer. The android:hardwareAccelerated="false" flag managed to do me a favour of not making the mentioned crash, but it was only a workaround and it made some other issues in the app. The real thing causing the problem was actually the NestedScrollView. At first putting android:transitionGroup="true" inside it, made the app work on some devices, but the problem was still there. So the final solution was to remove the NestedScrollView. I had found somewhere that it inside the SwipeRefreshLayout or WebView inside the NestedScrollView (I'm not sure since it was long ago) could cause trouble. Hope this was helpful!