Webview NameNotFoundException

Je reçois des erreurs de Crashlytics qui indiquent que certains périphériques sont manquants com.google.android.webview. Comment est-ce possible?

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp.app/com.myapp.ReaderActivity}: android.view.InflateException: Binary XML file line #29: Error inflating class com.myapp.MyWebView at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360) at android.app.ActivityThread.access$800(ActivityThread.java:144) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5221) at java.lang.reflect.Method.invoke(Method.java) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) Caused by: android.view.InflateException: Binary XML file line #29: Error inflating class com.myapp.MyWebView at android.view.LayoutInflater.createView(LayoutInflater.java:633) at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.createCustomViewInternal(SourceFile:206) at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.access$000(SourceFile:20) at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater$PrivateWrapperFactory2.onCreateView(SourceFile:297) at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:177) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733) at android.view.LayoutInflater.rInflate(LayoutInflater.java:806) at android.view.LayoutInflater.rInflate(LayoutInflater.java:809) at android.view.LayoutInflater.rInflate(LayoutInflater.java:809) at android.view.LayoutInflater.inflate(LayoutInflater.java:504) at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.inflate(SourceFile:60) at android.view.LayoutInflater.inflate(LayoutInflater.java:414) at android.view.LayoutInflater.inflate(LayoutInflater.java:365) at android.support.v7.app.ActionBarActivityDelegateBase.setContentView(SourceFile:228) at android.support.v7.app.ActionBarActivity.setContentView(SourceFile:102) at com.myapp.ReaderActivity.onCreate(SourceFile:120) at android.app.Activity.performCreate(Activity.java:5933) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360) at android.app.ActivityThread.access$800(ActivityThread.java:144) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5221) at java.lang.reflect.Method.invoke(Method.java) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Constructor.newInstance(Constructor.java) at java.lang.reflect.Constructor.newInstance(Constructor.java:288) at android.view.LayoutInflater.createView(LayoutInflater.java:607) at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.createCustomViewInternal(SourceFile:206) at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.access$000(SourceFile:20) at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater$PrivateWrapperFactory2.onCreateView(SourceFile:297) at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:177) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733) at android.view.LayoutInflater.rInflate(LayoutInflater.java:806) at android.view.LayoutInflater.rInflate(LayoutInflater.java:809) at android.view.LayoutInflater.rInflate(LayoutInflater.java:809) at android.view.LayoutInflater.inflate(LayoutInflater.java:504) at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.inflate(SourceFile:60) at android.view.LayoutInflater.inflate(LayoutInflater.java:414) at android.view.LayoutInflater.inflate(LayoutInflater.java:365) at android.support.v7.app.ActionBarActivityDelegateBase.setContentView(SourceFile:228) at android.support.v7.app.ActionBarActivity.setContentView(SourceFile:102) at com.myapp.ReaderActivity.onCreate(SourceFile:120) at android.app.Activity.performCreate(Activity.java:5933) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360) at android.app.ActivityThread.access$800(ActivityThread.java:144) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5221) at java.lang.reflect.Method.invoke(Method.java) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) Caused by: android.util.AndroidRuntimeException: android.content.pm.PackageManager$NameNotFoundException: com.google.android.webview at android.webkit.WebViewFactory.getFactoryClass(WebViewFactory.java:161) at android.webkit.WebViewFactory.getProvider(WebViewFactory.java:101) at android.webkit.WebView.getFactory(WebView.java:2185) at android.webkit.WebView.ensureProviderCreated(WebView.java:2180) at android.webkit.WebView.setOverScrollMode(WebView.java:2239) at android.view.View.(View.java:3581) at android.view.View.(View.java:3675) at android.view.ViewGroup.(ViewGroup.java:491) at android.widget.AbsoluteLayout.(AbsoluteLayout.java:55) at android.webkit.WebView.(WebView.java:538) at android.webkit.WebView.(WebView.java:483) at android.webkit.WebView.(WebView.java:466) at android.webkit.WebView.(WebView.java:453) at com.myapp.MyWebView.(SourceFile:31) at java.lang.reflect.Constructor.newInstance(Constructor.java) at java.lang.reflect.Constructor.newInstance(Constructor.java:288) at android.view.LayoutInflater.createView(LayoutInflater.java:607) at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.createCustomViewInternal(SourceFile:206) at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.access$000(SourceFile:20) at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater$PrivateWrapperFactory2.onCreateView(SourceFile:297) at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:177) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733) at android.view.LayoutInflater.rInflate(LayoutInflater.java:806) at android.view.LayoutInflater.rInflate(LayoutInflater.java:809) at android.view.LayoutInflater.rInflate(LayoutInflater.java:809) at android.view.LayoutInflater.inflate(LayoutInflater.java:504) at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.inflate(SourceFile:60) at android.view.LayoutInflater.inflate(LayoutInflater.java:414) at android.view.LayoutInflater.inflate(LayoutInflater.java:365) at android.support.v7.app.ActionBarActivityDelegateBase.setContentView(SourceFile:228) at android.support.v7.app.ActionBarActivity.setContentView(SourceFile:102) at com.myapp.ReaderActivity.onCreate(SourceFile:120) at android.app.Activity.performCreate(Activity.java:5933) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360) at android.app.ActivityThread.access$800(ActivityThread.java:144) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5221) at java.lang.reflect.Method.invoke(Method.java) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) Caused by: android.content.pm.PackageManager$NameNotFoundException: com.google.android.webview at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:114) at android.webkit.WebViewFactory.getFactoryClass(WebViewFactory.java:133) at android.webkit.WebViewFactory.getProvider(WebViewFactory.java:101) at android.webkit.WebView.getFactory(WebView.java:2185) at android.webkit.WebView.ensureProviderCreated(WebView.java:2180) at android.webkit.WebView.setOverScrollMode(WebView.java:2239) at android.view.View.(View.java:3581) at android.view.View.(View.java:3675) at android.view.ViewGroup.(ViewGroup.java:491) at android.widget.AbsoluteLayout.(AbsoluteLayout.java:55) at android.webkit.WebView.(WebView.java:538) at android.webkit.WebView.(WebView.java:483) at android.webkit.WebView.(WebView.java:466) at android.webkit.WebView.(WebView.java:453) at com.myapp.MyWebView.(SourceFile:31) at java.lang.reflect.Constructor.newInstance(Constructor.java) at java.lang.reflect.Constructor.newInstance(Constructor.java:288) at android.view.LayoutInflater.createView(LayoutInflater.java:607) at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.createCustomViewInternal(SourceFile:206) at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.access$000(SourceFile:20) at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater$PrivateWrapperFactory2.onCreateView(SourceFile:297) at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:177) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733) at android.view.LayoutInflater.rInflate(LayoutInflater.java:806) at android.view.LayoutInflater.rInflate(LayoutInflater.java:809) at android.view.LayoutInflater.rInflate(LayoutInflater.java:809) at android.view.LayoutInflater.inflate(LayoutInflater.java:504) at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.inflate(SourceFile:60) at android.view.LayoutInflater.inflate(LayoutInflater.java:414) at android.view.LayoutInflater.inflate(LayoutInflater.java:365) at android.support.v7.app.ActionBarActivityDelegateBase.setContentView(SourceFile:228) at android.support.v7.app.ActionBarActivity.setContentView(SourceFile:102) at com.myapp.ReaderActivity.onCreate(SourceFile:120) at android.app.Activity.performCreate(Activity.java:5933) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360) at android.app.ActivityThread.access$800(ActivityThread.java:144) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5221) at java.lang.reflect.Method.invoke(Method.java) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 

Et ce n’est qu’à partir d’appareils exécutant Lollipop. Je l’ai testé sur mon Nexus 5, mais je ne peux pas reproduire l’erreur. J’utilise proguard

Mon MyWebView ressemble à ceci:

 public class MyWebView extends WebView { public static final Ssortingng tag = MyWebView.class.getName(); private HtmlJSInterfaceNew js; public MyWebView(Context context) { super(context); gd = new GestureDetector(context, sogl); init(); } public MyWebView(Context context, AtsortingbuteSet attrs) { super(context, attrs); gd = new GestureDetector(context, sogl); init(); } public MyWebView(Context context, AtsortingbuteSet attrs, int defStyle) { super(context, attrs, defStyle); gd = new GestureDetector(context, sogl); init(); } @SuppressLint("NewApi") private void init() { setPadding(0, 0, 0, 0); MyWebViewClient myWebViewClient = new MyWebViewClient(); this.setWebViewClient(myWebViewClient); setWebChromeClient(new MyWebChromeClient()); if(!isInEditMode()) { getSettings().setAllowFileAccess(true); getSettings().setJavaScriptCanOpenWindowsAutomatically(false); getSettings().setJavaScriptEnabled(true); WebSettings webSettings = getSettings(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { webSettings.setAllowContentAccess(false); } webSettings.setUseWideViewPort(true); } } public void addMyJavascriptInterface(HtmlJSInterfaceNew htmlJSInterface, Ssortingng ssortingng) { js = htmlJSInterface; addJavascriptInterface(htmlJSInterface, ssortingng); } public class MyWebChromeClient extends WebChromeClient { public void onProgressChanged(WebView view, int progress) { } } } 

La cause principale est la suivante:

 android.util.AndroidRuntimeException: android.content.pm.PackageManager$NameNotFoundException: com.google.android.webview at android.webkit.WebViewFactory.getFactoryClass(WebViewFactory.java:161) 

Je pense donc que cela pourrait avoir quelque chose à voir avec Proguard et peut-être avec JavascriptInterface. Des idées?

EDIT: à partir de grepcode J’ai trouvé la méthode getFactoryClass:

 private static Class getFactoryClass() throws ClassNotFoundException { Application initialApplication = AppGlobals.getInitialApplication(); try { // First fetch the package info so we can log the webview package version. Ssortingng packageName = getWebViewPackageName(); sPackageInfo = initialApplication.getPackageManager().getPackageInfo(packageName, 0); Log.i(LOGTAG, "Loading " + packageName + " version " + sPackageInfo.versionName + " (code " + sPackageInfo.versionCode + ")"); // Construct a package context to load the Java code into the current app. Context webViewContext = initialApplication.createPackageContext(packageName, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY); initialApplication.getAssets().addAssetPath( webViewContext.getApplicationInfo().sourceDir); ClassLoader clazzLoader = webViewContext.getClassLoader(); Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "Class.forName()"); try { return (Class) Class.forName(CHROMIUM_WEBVIEW_FACTORY, true, clazzLoader); } finally { Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); } } catch (PackageManager.NameNotFoundException e) { // If the package doesn't exist, then try loading the null WebView instead. // If that succeeds, then this is a device without WebView support; if it fails then // swallow the failure, complain that the real WebView is missing and rethrow the // original exception. try { return (Class) Class.forName(NULL_WEBVIEW_FACTORY); } catch (ClassNotFoundException e2) { // Ignore. } Log.e(LOGTAG, "Chromium WebView package does not exist", e); throw new AndroidRuntimeException(e); } } 

Il est probable que cela se produise très rapidement après les mises à jour de l’application Android System WebView de Lollipop.

J’avais vu cette erreur dans la console de jeu Google Play, mais je n’avais jamais été capable de la reproduire sur mon Nexus 5, même si j’essayais vraiment d’empêcher mon application d’accéder à l’application Android System WebView:

 java.lang.RuntimeException: Unable to create application com.uninteresting.app.name: android.util.AndroidRuntimeException: android.content.pm.PackageManager$NameNotFoundException: com.google.android.webview 

Ensuite, nous avons appris que notre application était constamment en panne avec le message ci-dessus sur certains appareils immédiatement après la mise à jour de l’application System WebView, alors j’ai testé cela. Toujours pas de résultats, la vanille Nexus 5 a refusé de planter notre application! J’ai donc essayé d’autres téléphones d’autres fabricants (environ 75% de nos rapports provenaient d’appareils Samsung Galaxy) et soudainement nous nous sums écrasés. Ma méthodologie de test:

  1. Ouvrez votre application, assurez-vous que WebView s’affiche.
  2. Ouvrez Play Store, accédez à “Mes applications” et affichez “Android System WebView”. Désinstallez les mises à jour. Cela ne devrait pas vous faire tomber en panne, mais vous devriez voir le redémarrage forcé de votre application.
  3. Ouvrez votre application et laissez-la se remettre du redémarrage.
  4. Retournez dans le Play Store et mettez à jour Android System WebView.
  5. Re-focus votre application pendant le processus de mise à jour. Maintenant, si vous êtes sur un périphérique affecté, il devrait tomber en panne. Si ce n’est pas le cas, votre application sera simplement renvoyée en arrière-plan et redémarrée tranquillement.

Quelques petites mises en garde avec ce que j’ai dit jusqu’à présent:

  • Notre application commet l’erreur de démarrer un WebView très tôt , ce qui explique pourquoi nous sums incapables de créer une application dans notre message d’erreur. L’utilisateur n’a même pas besoin de regarder notre application pour qu’elle tombe en panne. Je doute que cela s’applique à vous, mais si votre application tente de redémarrer son activité contenant un WebView pendant ce scénario, cela l’expliquerait.
  • 100% de nos rapports proviennent de périphériques 5.0, je n’ai pas la moindre idée de la façon dont cela pourrait se produire sur quelque chose en dessous de Lollipop.
  • Nous voyons des rapports de Nexus 4 et Nexus 5 avec cette erreur, donc je ne sais pas pourquoi je ne peux pas le reproduire sur ces appareils. Peut-être une cause distincte, mais je dois approfondir cette question.

En bref, je ne pense pas immédiatement que vous faites quelque chose de mal avec ProGuard ou votre JavascriptInterface. Je m’appuie fortement sur le blâme du firmware comme étant la cause principale de la majorité des rapports, ce qui devrait se traduire par un processus de mise à jour sans heurts, ce qui en ferait un crash brutal de certaines applications.

Edit: J’ai effectué quelques tests supplémentaires et il s’avère que tous les périphériques qui ne sont pas tombés en panne sont la version 5.0 ou 5.0.1, alors que tous les périphériques qui étaient bloqués étaient la version 5.0.2. Je ne peux donc pas OEM plus.