NameNotFoundException webview

AndroidWebviewProguardAndroid 5.0-LollipopInflate Exception

Android Problem Overview


I am getting errors from Crashlytics that indicates that some devices are missing com.google.android.webview. How is that even 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)

And it is only from devices running Lollipop. I have tested it on my Nexus 5, but I can not reproduce the error. I am using proguard

My MyWebView looks like this:

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

The root cause most be:

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

So I am thinking it might have something to do with proguard and maybe the JavascriptInterface. Any ideas?

EDIT: from grepcode I have found the method 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);
        }
    }

Android Solutions


Solution 1 - Android

It's likely that this is happening in the very short time frame immediately after Lollipop's Android System WebView application updates.

I'd seen this error in the Google Play Dev Console, but also had never been able to reproduce it on my Nexus 5, regardless of how much I really tried to stop my app from having access to the Android System WebView app:

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

Then we got word that our app was consistently crashing with the above message on some devices immediately after the System WebView app updates, so I tested that. Still no results, the vanilla Nexus 5 refused to crash our app! So I tried other phones from other manufacturers (roughly 75% of our reports are from Samsung Galaxy devices) and suddenly we were crashing consistently. My testing methodology:

  1. Open your app, make sure a WebView is showing.
  2. Open Play Store, navigate to "My Apps," and bring up "Android System WebView." Uninstall updates. This shouldn't crash you, but you should see your app force-restart.
  3. Open your app back up and let it recover from the restart.
  4. Go back into the Play Store and update Android System WebView.
  5. Re-focus your app during the update process. Now, if you're on an affected device, it should crash. If not, your app will just be pushed to the background and quietly restarted.

A few little caveats with what I've said so far:

  • Our app makes the mistake of starting up a WebView extremely early, hence why we get "unable to create application" in our crash message. The user doesn't even have to be looking at our app for it to crash. I doubt this applies to you, but if your app attempts to restart its activity containing a WebView during this scenario, that would explain it.
  • 100% of our reports are from 5.0 devices, I have no earthly clue how this could occur on anything below Lollipop.
  • We do see reports of Nexus 4 and Nexus 5 with this error, so I don't know why I can't reproduce it on those devices. Might be a separate root cause, but I need to look further into that.

In short, I don't immediately think you're doing anything incorrect with ProGuard or your JavascriptInterface. I'm leaning very strongly toward blaming the firmware as the root cause of the majority of reports, resulting in what should be a smooth update process becoming one that instead causes some apps to outright crash.

Edit: I ran a few more tests and it turns out that all the devices that didn't crash are 5.0 or 5.0.1, while all the devices that did crash were 5.0.2, so I can't comfortably point my finger at OEMs anymore.

Solution 2 - Android

Easy way to check with androidx.webkit library:

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

Use WebViewCompat.getCurrentWebViewPackage method before (for example, ads):

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

Steps for reproduce:

  1. Disable or delete system WebView service
  • Disable: Go to system settings menu -> Apps -> Android System WebView -> Disable
  • Delete:
adb root
adb shell pm uninstall -k --user 0 com.google.android.webview
  1. Open smth WebView
  2. Then WebView will crashed if package unavailable: > E/WebViewFactory: Chromium WebView package does not exist > android.webkit.WebViewFactory$MissingWebViewPackageException: Failed > to load WebView provider: No WebView installed

Solution 3 - Android

This happens when chrome updates on android: during the update, the package does not count as installed and so attempts to look it up in the package manager will fail.

For my case it persisted for awhile longer (the app kept crashing) until I actually reboot / restart the device, then all is well.

There is nothing wrong with your code, its just how updates are handled.

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

Solution 4 - Android

I found a way to reproduce the problem (htc one (m8) android 6.0).
In my app I use Android System WebView component at start (in Activity.onCreate() method). I know that this is bad practice, but this is only for example.

Steps:

  1. open Google Play and remove updates of the Android System WebView
  2. launch your app
  3. go back to Google Play and launch installing updates of the Android System WebView and quickly return back to your app and waiting for your app is closed
  4. repeat step 1 and quickly return back to your app
  5. you will see error report
  6. sorry for my english...

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
QuestionKasper Finne NielsenView Question on Stackoverflow
Solution 1 - AndroidRiley CView Answer on Stackoverflow
Solution 2 - AndroidArtur BabichevView Answer on Stackoverflow
Solution 3 - AndroidAl-Kathiri KhalidView Answer on Stackoverflow
Solution 4 - AndroidilyamurometsView Answer on Stackoverflow