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

JavaAndroidWebview

Java Problem Overview


In Lollipop (API 22) every time in my application I show a webview the application crashes. I have multiple crashes in my android developer console related to this event.

No need to say that it works on Android 4, 6 and 7.

Reading the stack trace (posted at the end of this post), something bugs me

Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x2040003

I searched in the generated R.java without any luck, obviously because the ID does not exists, but it was worth a try.

Googling around the problem seems to be related to how lollipop handles the webview. I started a fresh AVD with lollipop based on a device I found on the crash reporter in GDC, and I can reproduce the problem.


Full stack trace:

android.view.InflateException: Binary XML file line #7: Error inflating class android.webkit.WebView
                  at android.view.LayoutInflater.createView(LayoutInflater.java:633)
                  at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55)
                  at android.view.LayoutInflater.onCreateView(LayoutInflater.java:682)
                  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:741)
                  at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
                  at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
                  at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
                  at it.artecoop.ibreviary.WebViewFragment.onCreateView(WebViewFragment.java:67)
                  at android.support.v4.app.Fragment.performCreateView(Fragment.java:2087)
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1113)
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1295)
                  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801)
                  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1682)
                  at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:541)
                  at android.os.Handler.handleCallback(Handler.java:739)
                  at android.os.Handler.dispatchMessage(Handler.java:95)
                  at android.os.Looper.loop(Looper.java:135)
                  at android.app.ActivityThread.main(ActivityThread.java:5254)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at java.lang.reflect.Method.invoke(Method.java:372)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
               Caused by: java.lang.reflect.InvocationTargetException
                  at java.lang.reflect.Constructor.newInstance(Native Method)
                  at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
                  at android.view.LayoutInflater.createView(LayoutInflater.java:607)
                  at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55at android.view.LayoutInflater.onCreateView(LayoutInflater.java:682at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:741at android.view.LayoutInflater.rInflate(LayoutInflater.java:806at android.view.LayoutInflater.inflate(LayoutInflater.java:504at android.view.LayoutInflater.inflate(LayoutInflater.java:414at it.artecoop.ibreviary.WebViewFragment.onCreateView(WebViewFragment.java:67at android.support.v4.app.Fragment.performCreateView(Fragment.java:2087at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1113at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1295at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1682at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:541at android.os.Handler.handleCallback(Handler.java:739at android.os.Handler.dispatchMessage(Handler.java:95at android.os.Looper.loop(Looper.java:135at android.app.ActivityThread.main(ActivityThread.java:5254at java.lang.reflect.Method.invoke(Native Method) 
                  at java.lang.reflect.Method.invoke(Method.java:372at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x2040003
                  at android.content.res.Resources.getText(Resources.java:299)
                  at android.content.res.Resources.getString(Resources.java:385)
                  at com.android.org.chromium.content.browser.ContentViewCore.setContainerView(ContentViewCore.java:684)
                  at com.android.org.chromium.content.browser.ContentViewCore.initialize(ContentViewCore.java:608)
                  at com.android.org.chromium.android_webview.AwContents.createAndInitializeContentViewCore(AwContents.java:631)
                  at com.android.org.chromium.android_webview.AwContents.setNewAwContents(AwContents.java:780)
                  at com.android.org.chromium.android_webview.AwContents.<init>(AwContents.java:619)
                  at com.android.org.chromium.android_webview.AwContents.<init>(AwContents.java:556)
                  at com.android.webview.chromium.WebViewChromium.initForReal(WebViewChromium.java:311)
                  at com.android.webview.chromium.WebViewChromium.access$100(WebViewChromium.java:96)
                  at com.android.webview.chromium.WebViewChromium$1.run(WebViewChromium.java:263)
                  at com.android.webview.chromium.WebViewChromium$WebViewChromiumRunQueue.drainQueue(WebViewChromium.java:123)
                  at com.android.webview.chromium.WebViewChromium$WebViewChromiumRunQueue$1.run(WebViewChromium.java:110)
                  at com.android.org.chromium.base.ThreadUtils.runOnUiThread(ThreadUtils.java:144)
                  at com.android.webview.chromium.WebViewChromium$WebViewChromiumRunQueue.addTask(WebViewChromium.java:107)
                  at com.android.webview.chromium.WebViewChromium.init(WebViewChromium.java:260)
                  at android.webkit.WebView.<init>(WebView.java:554)
                  at android.webkit.WebView.<init>(WebView.java:489)
                  at android.webkit.WebView.<init>(WebView.java:472)
                  at android.webkit.WebView.<init>(WebView.java:459)
                  at java.lang.reflect.Constructor.newInstance(Native Method) 
                  at java.lang.reflect.Constructor.newInstance(Constructor.java:288at android.view.LayoutInflater.createView(LayoutInflater.java:607at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55at android.view.LayoutInflater.onCreateView(LayoutInflater.java:682at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:741at android.view.LayoutInflater.rInflate(LayoutInflater.java:806at android.view.LayoutInflater.inflate(LayoutInflater.java:504at android.view.LayoutInflater.inflate(LayoutInflater.java:414at it.artecoop.ibreviary.WebViewFragment.onCreateView(WebViewFragment.java:67at android.support.v4.app.Fragment.performCreateView(Fragment.java:2087at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1113at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1295at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1682at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:541at android.os.Handler.handleCallback(Handler.java:739at android.os.Handler.dispatchMessage(Handler.java:95at android.os.Looper.loop(Looper.java:135at android.app.ActivityThread.main(ActivityThread.java:5254at java.lang.reflect.Method.invoke(Native Method) 
                  at java.lang.reflect.Method.invoke(Method.java:372at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698

Java Solutions


Solution 1 - Java

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:

Solution 2 - Java

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
}

Solution 3 - Java

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)

Solution 4 - Java

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

Solution 5 - Java

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

Solution 6 - Java

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.

Solution 7 - Java

Try use for creating webview:

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

Solution 8 - Java

And one more try to fix the problem. Should override this method in your activity:

    @Override
    public void applyOverrideConfiguration(final Configuration overrideConfiguration) {
        if (Build.VERSION.SDK_INT >= 21 && Build.VERSION.SDK_INT < 25) {
            overrideConfiguration.uiMode &= ~Configuration.UI_MODE_NIGHT_MASK;
        }
        super.applyOverrideConfiguration(overrideConfiguration);
    }

Solution 9 - Java

I was able to reproduce the crash on API 21 in the emulator.

So I tried to add this to the implementation, as described in the docs:

dependencies {
    def appcompat_version = "1.1.0"

    implementation "androidx.appcompat:appcompat:$appcompat_version"
    // For loading and tinting drawables on older versions of the platform
    implementation "androidx.appcompat:appcompat-resources:$appcompat_version"
}

Adding appcompat-resources did not fix the issue.

Maybe a future version will, but I wanted to mention that there seems to be a complementary resource library that is supposed to address this issue. So when trying to fix this with a new version of appcompat, add the appcompat-resources library with the same version.

Reverting to androidx.appcompat:appcompat:1.0.2 did fix the issue as a workaround.

Solution 10 - Java

The below code will fix the problem. Please add it in your Activity:

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

Solution 11 - Java

I used the latest version from this source. Please check and use your own based on what you think is best.

In case you want to skip, below implementation solves the issue:

implementation 'androidx.appcompat:appcompat:1.2.0'

Solution 12 - Java

Just as a side note, I struggled for a while even though I downgraded to 1.0.2, just because I seemed to have a transitive dependency to appcompat:1.1.0 via androidx.constraintlayout:constraintlayout:2.0.0-beta3. Once I downgraded that to constraintlayout:1.1.3 everything worked fine

(According to https://issuetracker.google.com/issues/141351441 issue will be fixed soon with appcompat:1.2.0-alpha02)

Solution 13 - Java

戴文锦 was right for me too. But downgrading just androidx.appcompat:appcompat:1.1.0 to 1.0.2 did not succeed.

I downgraded all my previously upgraded androidx versions from

implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.android.material:material:1.1.0-alpha10'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.1.0-beta04'
implementation 'androidx.viewpager2:viewpager2:1.0.0-beta04'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
implementation 'androidx.preference:preference:1.1.0'
implementation 'androidx.core:core:1.2.0-alpha04'

back to

implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.android.material:material:1.1.0-alpha09'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.1.0-beta03'
implementation 'androidx.viewpager2:viewpager2:1.0.0-beta03'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.vectordrawable:vectordrawable:1.1.0-rc01'
implementation 'androidx.preference:preference:1.1.0-rc01'
implementation 'androidx.core:core:1.2.0-alpha03'

A reminder that Googles code is by far not bug free and well tested and that someone should never upgrade the versions flippantly.

Solution 14 - Java

/**
 * Customized WebView to avoid crashing on Android 5 and 6 (API level 21 to 23)
 * If the Android System WebView is old and is not updated, the WebView view inflation fails.
 * To reproduce the issue, try on OS 5 or 6 with Android System WebView 72.0.3626.76 (this version is just a reference point from being which we saw no crashes)
 */
class BrilliantWebView : WebView {

   companion object {
       private fun getBrilliantContext(context: Context?) =
            if (!OSUtils.hasNougat()) // OS < 24 or OS < 7.0
                context?.createConfigurationContext(Configuration())
            else
                context
    }

   constructor(context: Context?) : super(getBrilliantContext(context))
   constructor(context: Context?, attrs: AttributeSet?) : super(getBrilliantContext(context), attrs)
   constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(getBrilliantContext(context), attrs, defStyleAttr)
}

Solution 15 - Java

AppCompat 1.2.0-alpha02 was released today, so you can use

implementation 'androidx.appcompat:appcompat:1.2.0-alpha02'

which will fix WebView issues on Lollipop.

Solution 16 - Java

I was able to reproduce this issue on a Nexus 7 API 22. The issue is fixed by updating the tablet's version of Android System WebView from version 39 (2237560-arm) to version 79.0.3945.136

This isn't in my control for a user to do this, but it is a solution if you need to help someone use your app immediately.

Solution 17 - Java

The issue was solve for my by downgrading to implementation 'androidx.appcompat:appcompat:1.0.2'

Solution 18 - Java

In my case a problem was in method

fun getUserId(): Int = userId

of a MainActivity. I don't know why it affects WebView. getUserId() is neither overriden, nor public method of the Activity class. If I rename or remove this method, WebView starts to open. Also trying to change

private var userId: Int = 0

to

var userId: Int = 0
    private set

leads to the same exception. I understood that when had seen an exception: Caused by: java.lang.SecurityException: Permission Denial: null asks to run as user 123456 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL or android.permission.INTERACT_ACROSS_USERS. In that case user=123456 was in fact my authorized user, that was used in some requests, not in WebView. I suspect Android uses userId as a local user_id for its processes.

As many other people noticed we could use appcompat:1.1.0 or 1.0.2 and extend WebView class. In emulator 21 without Google Play Services this WebView will crash on long touch over text labels, but on typical devices everything is allright.

Solution 19 - Java

Instead of changing version of any dependency, I implemented programmatically generation of webView as a solution.

The problem actually looks like starting with reading layout from xml file. So if programmatic way is applicable solution for you please check bellow sample.

private WebView generateWebView(){
    WebView wv = new WebView(YourContext);
    wv.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    wv.setFitsSystemWindows(false); // your preferences
    wv.setVerticalScrollBarEnabled(false); // your preferences
    wv.setPadding(15,15,15,15); // your preferences
    return wv;
}

Than just add into your parent view:

LinearLayout scrollContainer = findViewById(R.id.scrollContainer);
scrollContainer.addView(generateWebView());

Solution 20 - Java

Check version. Androidx appcompat and Google material version keep same always.

implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation "androidx.cardview:cardview:1.0.0"

enter image description here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionValerioView Question on Stackoverflow
Solution 1 - Java戴文锦View Answer on Stackoverflow
Solution 2 - JavaPrawiraView Answer on Stackoverflow
Solution 3 - JavaSpaceBisonView Answer on Stackoverflow
Solution 4 - JavasnachmsmView Answer on Stackoverflow
Solution 5 - JavaA R Mythili SaranView Answer on Stackoverflow
Solution 6 - JavaS. GisselView Answer on Stackoverflow
Solution 7 - JavaikostetView Answer on Stackoverflow
Solution 8 - JavaHotIceCreamView Answer on Stackoverflow
Solution 9 - JavaManuelView Answer on Stackoverflow
Solution 10 - JavaavinashaView Answer on Stackoverflow
Solution 11 - JavaF.MysirView Answer on Stackoverflow
Solution 12 - JavaJens SchmittView Answer on Stackoverflow
Solution 13 - JavaS. GisselView Answer on Stackoverflow
Solution 14 - Javadisplay nameView Answer on Stackoverflow
Solution 15 - JavaDimitris PattasView Answer on Stackoverflow
Solution 16 - JavaTGruenwaldView Answer on Stackoverflow
Solution 17 - JavaAshView Answer on Stackoverflow
Solution 18 - JavaCoolMindView Answer on Stackoverflow
Solution 19 - JavaRıdvan Nuri GöçmenView Answer on Stackoverflow
Solution 20 - JavaMahmudul hasan MuhibView Answer on Stackoverflow