web-dev-qa-db-fra.com

android.view.InflateException Erreur de gonflage de la classe Android.webkit.WebView

Dans Lollipop (API 22), chaque fois dans mon application, je montre une vue Web de l'application qui plante. J'ai plusieurs plantages dans ma Android liée à cet événement.

Inutile de dire que cela fonctionne sur Android 4, 6 et 7.

Lire la trace de la pile (posté à la fin de ce post), quelque chose me dérange

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

J'ai cherché dans le R.Java généré sans aucune chance, évidemment parce que l'ID n'existe pas, mais cela valait la peine d'essayer.

La recherche sur le problème semble liée à la façon dont Lollipop gère la vue Web. J'ai commencé un nouveau AVD avec Lollipop basé sur un appareil que j'ai trouvé sur le reporter de crash dans GDC, et je peux reproduire le problème.


Trace de pile complète:

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: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: 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:288) 
                  at Android.view.LayoutInflater.createView(LayoutInflater.Java:607) 
                  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) 
93
Valerio

si vous utilisez "androidx.appcompat: appcompat: 1.1.0", essayez plutôt "androidx.appcompat: appcompat: 1.0.2". il semble que 1.1.0 ne gère pas le bogue avec la vue Web dans Android 5.1.1.

6
戴文锦

Si vous souhaitez gonfler le WebView à partir d'une disposition XML, vous pouvez l'envelopper dans une petite sous-classe Nice (basée sur réponse d'ikostet ):

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: maintenant encore plus agréable avec Kotlin

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

Essayez d'utiliser pour créer une vue Web:

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

mon conseil est d'utiliser custom/new Configuration uniquement lorsque "original one" cause des problèmes, donc Lollipop uniquement. Le code @SpaceBizon fonctionne bien jusqu'à Android 8.x, le 9 et Q (actuellement en version bêta), chaque pression de sélection/liste déroulante n'affichera pas le sélecteur AlertDialog, au lieu de cette fuite de mémoire se produit ... sous la méthode getFixedContext fixe avec le code de version correct "iffed"

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

J'ai pu reproduire ce problème sur une Nexus 7 API 22. Le problème est résolu en mettant à jour la version de la tablette de Android System WebView from version 39 (2237560-arm) = à version 79.0.3945.136

Ce n'est pas sous mon contrôle pour un utilisateur de le faire, mais c'est une solution si vous devez aider quelqu'un à utiliser votre application immédiatement.

0
TGruenwald

Le code ci-dessous résoudra les problèmes. Veuillez l'ajouter dans votre Activity:

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

Dans mon cas, un problème de méthode

fun getUserId(): Int = userId

d'une activité principale. Je ne sais pas pourquoi cela affecte WebView. getUserId() n'est ni surchargée, ni méthode publique de la classe Activity. Si je renomme ou supprime cette méthode, WebView commence à s'ouvrir. Essayer également de changer

private var userId: Int = 0

à

var userId: Int = 0
    private set

conduit à la même exception. J'ai compris que quand avait vu une 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. Dans ce cas, user = 123456 était en fait mon utilisateur autorisé, qui était utilisé dans certaines requêtes, pas dans WebView. Je soupçonne Android utilise userId comme id_utilisateur local pour ses processus.

Comme beaucoup d'autres personnes ont remarqué que nous pouvions utiliser appcompat:1.1.0 Ou 1.0.2 Et étendre la classe WebView. Dans l'émulateur 21 sans les services Google Play, ce WebView se bloquera sur une longue touche sur les étiquettes de texte, mais sur les appareils typiques, tout va bien.

0
CoolMind