NameNotFoundException веб-просмотр

116

Я получаю сообщение об ошибке от Crashlytics, указывающее на то, что на некоторых устройствах отсутствует com.google.android.webview. Как это вообще возможно?

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)

И это только с устройств под управлением Lollipop. Я тестировал его на своем Nexus 5, но не могу воспроизвести ошибку. Я использую прогард

Мой MyWebView выглядит так:

public class MyWebView extends WebView {

    public static final String tag = MyWebView.class.getName();
    private HtmlJSInterfaceNew js;

    public MyWebView(Context context) {
        super(context);
        gd = new GestureDetector(context, sogl);
        init();
    }

    public MyWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        gd = new GestureDetector(context, sogl);
        init();
    }

    public MyWebView(Context context, AttributeSet 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, String string) {
        js = htmlJSInterface;
        addJavascriptInterface(htmlJSInterface, string);
    }

    public class MyWebChromeClient extends WebChromeClient
    {
        public void onProgressChanged(WebView view, int progress) {
        }
    }
}

Основная причина:

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

Поэтому я думаю, что это может иметь какое-то отношение к proguard и, возможно, к JavascriptInterface. Любые идеи?

РЕДАКТИРОВАТЬ: из grepcode я нашел метод getFactoryClass:

private static Class<WebViewFactoryProvider> getFactoryClass() throws ClassNotFoundException {
        Application initialApplication = AppGlobals.getInitialApplication();
        try {
            // First fetch the package info so we can log the webview package version.
            String 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<WebViewFactoryProvider>) 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<WebViewFactoryProvider>) Class.forName(NULL_WEBVIEW_FACTORY);
            } catch (ClassNotFoundException e2) {
                // Ignore.
            }
            Log.e(LOGTAG, "Chromium WebView package does not exist", e);
            throw new AndroidRuntimeException(e);
        }
    }
Каспер Финне Нильсен
источник
2
Я тоже вижу это в наших данных Crashlytics. В основном Lollipop, но также и 4.0.4. Устройства включают Nexus 7, Galaxy S5, Galaxy Discover. Якобы ни один из них не внедрен. Как / почему на устройстве может отсутствовать com.google.android.webview? Это затрагивает очень небольшое количество пользователей, и у нас есть много других пользователей с этими устройствами, у которых НЕ возникает этой проблемы. Хм ...
Роберт Некич

Ответы:

99

Вероятно, это происходит в очень короткие сроки сразу после обновления приложения Lollipop Android System WebView.

Я видел эту ошибку в консоли разработчика Google Play, но также никогда не мог воспроизвести ее на своем Nexus 5, независимо от того, насколько я действительно пытался помешать моему приложению получить доступ к приложению 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

Затем мы получили сообщение о том, что наше приложение постоянно дает сбой с вышеуказанным сообщением на некоторых устройствах сразу после обновления приложения System WebView, поэтому я проверил это. По-прежнему никаких результатов, ванильный Nexus 5 отказался вылетать из нашего приложения! Поэтому я пробовал другие телефоны других производителей (примерно 75% наших отчетов приходятся на устройства Samsung Galaxy), и внезапно у нас постоянно возникали сбои. Моя методика тестирования:

  1. Откройте свое приложение и убедитесь, что отображается WebView.
  2. Откройте Play Store, перейдите в «Мои приложения» и откройте «Android System WebView». Удалите обновления. Это не должно привести к сбою, но вы должны увидеть принудительный перезапуск приложения.
  3. Откройте резервную копию приложения и дайте ему восстановиться после перезапуска.
  4. Вернитесь в Play Store и обновите Android System WebView.
  5. Перефокусируйте свое приложение в процессе обновления. Теперь, если вы используете уязвимое устройство, оно должно аварийно завершить работу. В противном случае ваше приложение будет просто переведено в фоновый режим и перезапущено.

Несколько небольших оговорок в отношении того, что я сказал до сих пор:

  • Наше приложение совершает ошибку, очень рано запускает WebView , поэтому в нашем сообщении о сбое мы получаем сообщение «невозможно создать приложение». Пользователю даже не нужно смотреть на наше приложение, чтобы оно упало. Я сомневаюсь, что это относится к вам, но если ваше приложение попытается перезапустить свою активность, содержащую WebView, во время этого сценария, это объяснит это.
  • 100% наших отчетов поступают с устройств 5.0, я не имею ни малейшего представления о том, как это могло произойти с чем-либо ниже Lollipop.
  • Мы действительно видим отчеты о Nexus 4 и Nexus 5 с этой ошибкой, поэтому я не знаю, почему я не могу воспроизвести ее на этих устройствах. Возможно, это отдельная основная причина, но мне нужно глубже изучить это.

Короче говоря, я не сразу думаю, что вы делаете что-то неправильно с ProGuard или своим JavascriptInterface. Я очень сильно склоняюсь к тому, чтобы обвинить прошивку как основную причину большинства отчетов, в результате чего плавный процесс обновления превращается в тот, который вместо этого приводит к полному сбою некоторых приложений.

Изменить: я провел еще несколько тестов, и оказалось, что все устройства, которые не вышли из строя, были 5.0 или 5.0.1, в то время как все устройства, которые вызвали сбой, были 5.0.2, поэтому я не могу удобно указать пальцем на OEM больше нет.

Райли С
источник
У нас есть несколько таких ошибок, о которых сообщается в наших данных Crashlytics от пользователей с Android 4.0.4, 4.2.2, 4.4.2, 5.0, 5.0.1, 5.0.2 и 5.1. Очень редко: около 30 отчетов для приложения с несколькими миллионами установок.
Роберт Некич
@RobertNekic При сравнимом количестве установок мы видели это только в 5.0 и 5.1, и, исходя из причины нашей проблемы, я не могу понять, как это могло бы произойти на более низких версиях. Я хотел бы знать, что конкретно их вызывает.
Riley C
1
@androiddeveloper. Просто погуглите: code.google.com/p/android/issues/detail?id=175124 и groups.google.com/forum/#!topic/google-admob-ads-sdk/… . Кажется, это затрагивает многих людей.
Джаред Берроуз,
2
Вот правильная информация от члена команды хрома. code.google.com/p/chromium/issues/detail?id=506369 Кажется, на данный момент не может быть решено
MatPag,
1
@RileyC, как сказал Мэт, это не будет исправлено, как указано в этом комментарии . В нем говорится, что это может происходить, когда клиент WebView обновляется. После завершения установки приложение перезапустится.
Суфиан
0

Это происходит, когда хром обновляется на android: во время обновления пакет не считается установленным, и поэтому попытки найти его в диспетчере пакетов не удастся.

В моем случае это сохранялось еще некоторое время (приложение продолжало давать сбой), пока я не перезагрузил / не перезапустил устройство , тогда все в порядке.

В вашем коде нет ничего плохого, дело в том, как обрабатываются обновления.

Источник: https://bugs.chromium.org/p/chromium/issues/detail?id=506369

Аль-Катири Халид
источник
0

Нашел способ воспроизвести проблему ( htc one (m8) android 6.0 ).
В своем приложении я использую компонент Android System WebView при запуске (в методе Activity.onCreate () ). Я знаю, что это плохая практика, но это только для примера.

шаги:

  1. откройте Google Play и удалите обновления Android System WebView
  2. запустите свое приложение
  3. вернитесь в Google Play и запустите установку обновлений системы Android WebView, быстро вернитесь в свое приложение и дождитесь закрытия приложения.
  4. повторите шаг 1 и быстро вернитесь в свое приложение
  5. вы увидите отчет об ошибке
  6. Извините за мой английский...
ilyamuromets
источник