【问题标题】:NameNotFoundException webviewNameNotFoundException 网络视图
【发布时间】:2015-06-16 23:48:24
【问题描述】:

我从 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 上对其进行了测试,但我无法重现该错误。我正在使用 proguard

我的 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);
        }
    }

【问题讨论】:

  • 我在我们的 Crashlytics 数据中也看到了这些。大多数是棒棒糖,但也有一些 4.0.4。设备包括 Nexus 7、Galaxy S5、Galaxy Discover。据说他们都没有扎根。设备如何/为什么会缺少 com.google.android.webview?它影响了极少数用户,我们还有许多其他使用这些设备的用户没有遇到此问题。嗯……

标签: android webview proguard android-5.0-lollipop inflate-exception


【解决方案1】:

这很可能发生在 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% 来自三星 Galaxy 设备),突然间我们一直在崩溃。我的测试方法:

  1. 打开您的应用,确保正在显示 WebView。
  2. 打开 Play 商店,导航到“我的应用程序”,然后调出“Android 系统 WebView。”卸载更新。这不应该让你崩溃,但你 应该会看到您的应用强制重启。
  3. 打开您的应用备份,让它从重启中恢复。
  4. 返回 Play 商店并更新 Android System WebView。
  5. 在更新过程中重新关注您的应用程序。现在,如果你在 受影响的设备,它应该崩溃。如果没有,您的应用程序将只是 被推到后台并安静地重新启动。

到目前为止我所说的一些小警告:

  • 我们的应用错误地极早地启动了 WebView,因此我们的崩溃消息中出现“无法创建应用程序”的原因。用户甚至不必查看我们的应用程序就会崩溃。我怀疑这是否适用于您,但如果您的应用在这种情况下尝试重新启动包含 WebView 的 Activity,那就可以解释了。
  • 我们的报告 100% 来自 5.0 设备,我不知道这怎么会发生在低于 Lollipop 的任何设备上。
  • 我们确实看到 Nexus 4 和 Nexus 5 出现此错误的报告,所以我不知道为什么我无法在这些设备上重现它。可能是一个单独的根本原因,但我需要进一步调查。

简而言之,我不会立即认为您在使用 ProGuard 或 JavascriptInterface 时做错了什么。我非常倾向于将固件归咎于大多数报告的根本原因,导致原本应该平稳的更新过程变成了导致某些应用彻底崩溃的过程。

编辑:我又进行了几次测试,结果发现所有没有崩溃的设备都是 5.0 或 5.0.1,而所有崩溃的设备都是 5.0.2,所以我不能再轻松地将矛头指向原始设备制造商了。

【讨论】:

  • 我们的 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 上看到过这种情况,根据我们问题的原因,我看不出它会在更低的版本上如何发生.我很想知道是什么导致了这些问题。
  • @androiddeveloper 只需 google 一下:code.google.com/p/android/issues/detail?id=175124groups.google.com/forum/#!topic/google-admob-ads-sdk/…。这似乎影响了很多人。
  • 这里是来自 Chromium 团队成员的正确信息。 code.google.com/p/chromium/issues/detail?id=506369目前好像解决不了
  • @RileyC 正如 Mat 所说,它不会像 this comment 中所说的那样被修复。它说在更新 WebView 客户端时可能会发生这种情况。安装完成后应用会重新启动。
【解决方案2】:

使用androidx.webkit 库检查的简单方法:

dependencies {
    ...
    implementation 'androidx.webkit:webkit:1.4.0'
}

在之前使用WebViewCompat.getCurrentWebViewPackage方法(例如广告):

val webViewPackageInfo = WebViewCompat.getCurrentWebViewPackage(appContext)
Timber.d("? web view package info: %s", webViewPackageInfo?.toString())
val isWebViewPackageAvailable = webViewPackageInfo != null
prepareWithAds(canPlayAds = isWebViewPackageAvailable)

复制步骤:

  1. 禁用或删除系统 WebView 服务
  • 禁用: 转到系统设置菜单 -> 应用程序 -> Android System WebView -> 禁用
  • 删除:
adb root
adb shell pm uninstall -k --user 0 com.google.android.webview
  1. 打开网页视图
  2. 如果包不可用,WebView 会崩溃:

E/WebViewFactory: Chromium WebView 包不存在 android.webkit.WebViewFactory$MissingWebViewPackageException: 失败 加载 WebView 提供程序:未安装 WebView

【讨论】:

    【解决方案3】:

    在 android 上的 chrome 更新时会发生这种情况:在更新期间,该包不计为已安装,因此尝试在包管理器中查找它会失败。

    就我而言,它持续了一段时间(应用程序不断崩溃),直到我真正重新启动/重新启动设备,然后一切都很好。

    您的代码没有任何问题,只是处理更新的方式。

    来源:https://bugs.chromium.org/p/chromium/issues/detail?id=506369

    【讨论】:

      【解决方案4】:

      我找到了重现问题的方法(htc one (m8) android 6.0)。
      在我的应用程序中,我在开始时使用 Android System WebView 组件(在 Activity.onCreate() 方法中)。我知道这是不好的做法,但这只是示例。

      步骤:

      1. 打开 Google Play 并删除 Android 系统的更新 网络视图
      2. 启动您的应用
      3. 返回 Google Play 并启动 快速安装 Android System WebView 更新 返回您的应用并等待您的应用关闭
      4. 重复 第 1 步并快速返回您的应用
      5. 您会看到错误报告
      6. 对不起我的英语...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-05-06
        • 2016-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-13
        相关资源
        最近更新 更多