Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android.view.InflateException Error inflating class android.webkit.WebView

If you use androidx.appcompat:appcompat:1.1.0, try androidx.appcompat:appcompat:1.0.2 instead. it seems that 1.1.0 doesn't fix the bug with WebView in Android 5.1.1.

Feb-2020 update: Reverting to 1.0.2 stopped working for many people (including my app), but using the current version of androidx.appcompat:appcompat:1.2.0-alpha02 did fix the crash. (I was seeing it on a Huawei P8 Lite running Android 5.0 during Google's automated "Pre-launch report" testing).

Jun-2020 update: There are newer releases available than the one mentioned in the Feb-2020 update, you can see the currently available versions here:

  • https://developer.android.com/jetpack/androidx/releases/appcompat

If you are using androidx.appcompat:appcompat:1.1.0 and don't want to downgrade to androidx.appcompat:appcompat:1.0.2 or upgrading to androidx.appcompat:appcompat:1.2.0-alpha03, there's another solution which is described in this comment on the Google Issue Tracker.

I noticed that after calling applyOverrideConfiguration, Context.getAssets() and Context.getResources().getAssets() are not returning the same AssetManager object. The AssetManager returned from Context.getAssets() can't access resources in other packages (including the system WebView package), causing WebView to crash. If I override Context.getAssets() to return getResources().getAssets(), the problem is gone.

Based on that comment, you can override the getAssets() in the WebView's Activity so that it returns getResources().getAssets() instead to solve the issue.

Java

@Override
public AssetManager getAssets() {
    return getResources().getAssets();
}

Kotlin

override fun getAssets(): AssetManager {
    return resources.assets
}

Warning: this workaround might also break some things; see the comments for details

If you'd like to inflate the WebView from an XML layout, you can wrap it in a nice little subclass (based on ikostet's answer):

public class LollipopFixedWebView extends WebView {
    public LollipopFixedWebView(Context context) {
        super(getFixedContext(context));
    }

    public LollipopFixedWebView(Context context, AttributeSet attrs) {
        super(getFixedContext(context), attrs);
    }

    public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(getFixedContext(context), attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(getFixedContext(context), attrs, defStyleAttr, defStyleRes);
    }

    public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr, boolean privateBrowsing) {
        super(getFixedContext(context), attrs, defStyleAttr, privateBrowsing);
    }

    public static Context getFixedContext(Context context) {
        return context.createConfigurationContext(new Configuration());
    }
}

EDIT: now even nicer with Kotlin

class LollipopFixedWebView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
    defStyleRes: Int = 0
) : WebView(context.createConfigurationContext(Configuration()), attrs, defStyleAttr, defStyleRes)

my advice is to use custom/new Configuration only when "original one" is causing problems, so on Lollipop only. @SpaceBizon code work well till Android 8.x, on 9 and Q (currenly beta) every select/dropdown press won't show AlertDialog picker, instead of that memory leak occurs... below fixed getFixedContext method with "iffed" proper version code

public class LollipopFixedWebView extends WebView {

    public LollipopFixedWebView(Context context) {
        super(getFixedContext(context));
    }

    public LollipopFixedWebView(Context context, AttributeSet attrs) {
        super(getFixedContext(context), attrs);
    }

    public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(getFixedContext(context), attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(getFixedContext(context), attrs, defStyleAttr, defStyleRes);
    }

    private static Context getFixedContext(Context context) {
        if (Build.VERSION.SDK_INT >= 21 && Build.VERSION.SDK_INT < 23) // Android Lollipop 5.0 & 5.1
            return context.createConfigurationContext(new Configuration());
        return context;
    }
}

If you are using androidx.appcompat:appcompat:1.1.0, either change to androidx.appcompat:appcompat:1.0.2 or if you want to use DayNight Theme, override applyOverrideConfiguration in your activity as follows. (Note: This requires app restart while switching from Dark Theme to Light Theme and vice versa).

override fun applyOverrideConfiguration(overrideConfiguration: Configuration?) {
        if (Build.VERSION.SDK_INT in 21..25 && (resources.configuration.uiMode ==  applicationContext.resources.configuration.uiMode)) {
                return
        }
        super.applyOverrideConfiguration(overrideConfiguration)
}

If you are not relying on DayNight theme switching (or other UiMode events), you can add android:configChanges="uiMode" to the webview activity manifest to prevent AppCompatDelegate updating the Resources configuration and thereby messing up the webview inflation.


Try use for creating webview:

mWebView = new WebView(getActivity().createConfigurationContext(new Configuration()));