错误膨胀类android.webkit.WebView偶尔会在生产中发生

时间:2015-07-30 19:12:03

标签: android webview

我的应用程序位于Google Play上,并且在大多数设备(数千名用户)上运行良好。但在极少数情况下(每日活跃用户百分比的一小部分),当我在Error inflating class android.webkit.WebView方法中为我的片段扩充布局时,我得到onCreateView。 完整堆栈跟踪如下:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tapmedia.tapito/com.tapmedia.tapito.LockscreenActivity}: android.view.InflateException: Binary XML file line #20: Error inflating class android.webkit.WebView
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2694)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2759)
   at android.app.ActivityThread.access$900(ActivityThread.java:178)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:145)
   at android.app.ActivityThread.main(ActivityThread.java:5944)
   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:1399)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: android.view.InflateException: Binary XML file line #20: Error inflating class android.webkit.WebView
   at android.view.LayoutInflater.createView(LayoutInflater.java:640)
   at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55)
   at android.view.LayoutInflater.onCreateView(LayoutInflater.java:689)
   at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:748)
   at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
   at android.view.LayoutInflater.rInflate(LayoutInflater.java:821)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
   at com.tapmedia.tapito.WebViewFragment.onCreateView(SourceFile:84)
   at android.support.v4.app.Fragment.performCreateView(SourceFile:1789)
   at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:924)
   at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1116)
   at android.support.v4.app.FragmentManagerImpl.onCreateView(SourceFile:2196)
   at android.support.v4.app.FragmentActivity.onCreateView(SourceFile:300)
   at android.support.v7.app.AppCompatDelegateImplV7.callActivityOnCreateView(SourceFile:838)
   at android.support.v7.app.AppCompatDelegateImplV11.callActivityOnCreateView(SourceFile:34)
   at android.support.v7.app.AppCompatDelegateImplV7.onCreateView(SourceFile:826)
   at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(SourceFile:44)
   at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:732)
   at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:366)
   at android.support.v7.app.AppCompatDelegateImplV7.setContentView(SourceFile:249)
   at android.support.v7.app.AppCompatActivity.setContentView(SourceFile:106)
   at com.tapmedia.tapito.LockscreenActivity.onCreate(SourceFile:103)
   at android.app.Activity.performCreate(Activity.java:6289)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2647)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2759)
   at android.app.ActivityThread.access$900(ActivityThread.java:178)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:145)
   at android.app.ActivityThread.main(ActivityThread.java:5944)
   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:1399)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
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:614)
   at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55)
   at android.view.LayoutInflater.onCreateView(LayoutInflater.java:689)
   at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:748)
   at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
   at android.view.LayoutInflater.rInflate(LayoutInflater.java:821)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
   at com.tapmedia.tapito.WebViewFragment.onCreateView(SourceFile:84)
   at android.support.v4.app.Fragment.performCreateView(SourceFile:1789)
   at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:924)
   at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1116)
   at android.support.v4.app.FragmentManagerImpl.onCreateView(SourceFile:2196)
   at android.support.v4.app.FragmentActivity.onCreateView(SourceFile:300)
   at android.support.v7.app.AppCompatDelegateImplV7.callActivityOnCreateView(SourceFile:838)
   at android.support.v7.app.AppCompatDelegateImplV11.callActivityOnCreateView(SourceFile:34)
   at android.support.v7.app.AppCompatDelegateImplV7.onCreateView(SourceFile:826)
   at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(SourceFile:44)
   at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:732)
   at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:366)
   at android.support.v7.app.AppCompatDelegateImplV7.setContentView(SourceFile:249)
   at android.support.v7.app.AppCompatActivity.setContentView(SourceFile:106)
   at com.tapmedia.tapito.LockscreenActivity.onCreate(SourceFile:103)
   at android.app.Activity.performCreate(Activity.java:6289)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2647)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2759)
   at android.app.ActivityThread.access$900(ActivityThread.java:178)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:145)
   at android.app.ActivityThread.main(ActivityThread.java:5944)
   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:1399)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
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:2193)
   at android.webkit.WebView.ensureProviderCreated(WebView.java:2188)
   at android.webkit.WebView.setOverScrollMode(WebView.java:2247)
   at android.view.View.(View.java:3795)
   at android.view.View.(View.java:3909)
   at android.view.ViewGroup.(ViewGroup.java:507)
   at android.widget.AbsoluteLayout.(AbsoluteLayout.java:55)
   at android.webkit.WebView.(WebView.java:547)
   at android.webkit.WebView.(WebView.java:492)
   at android.webkit.WebView.(WebView.java:475)
   at android.webkit.WebView.(WebView.java:462)
   at java.lang.reflect.Constructor.newInstance(Constructor.java)
   at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
   at android.view.LayoutInflater.createView(LayoutInflater.java:614)
   at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55)
   at android.view.LayoutInflater.onCreateView(LayoutInflater.java:689)
   at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:748)
   at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
   at android.view.LayoutInflater.rInflate(LayoutInflater.java:821)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
   at com.tapmedia.tapito.WebViewFragment.onCreateView(SourceFile:84)
   at android.support.v4.app.Fragment.performCreateView(SourceFile:1789)
   at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:924)
   at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1116)
   at android.support.v4.app.FragmentManagerImpl.onCreateView(SourceFile:2196)
   at android.support.v4.app.FragmentActivity.onCreateView(SourceFile:300)
   at android.support.v7.app.AppCompatDelegateImplV7.callActivityOnCreateView(SourceFile:838)
   at android.support.v7.app.AppCompatDelegateImplV11.callActivityOnCreateView(SourceFile:34)
   at android.support.v7.app.AppCompatDelegateImplV7.onCreateView(SourceFile:826)
   at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(SourceFile:44)
   at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:732)
   at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:366)
   at android.support.v7.app.AppCompatDelegateImplV7.setContentView(SourceFile:249)
   at android.support.v7.app.AppCompatActivity.setContentView(SourceFile:106)
   at com.tapmedia.tapito.LockscreenActivity.onCreate(SourceFile:103)
   at android.app.Activity.performCreate(Activity.java:6289)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2647)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2759)
   at android.app.ActivityThread.access$900(ActivityThread.java:178)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:145)
   at android.app.ActivityThread.main(ActivityThread.java:5944)
   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:1399)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: android.content.pm.PackageManager$NameNotFoundException: com.google.android.webview
   at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:137)
   at android.webkit.WebViewFactory.getFactoryClass(WebViewFactory.java:133)
   at android.webkit.WebViewFactory.getProvider(WebViewFactory.java:101)
   at android.webkit.WebView.getFactory(WebView.java:2193)
   at android.webkit.WebView.ensureProviderCreated(WebView.java:2188)
   at android.webkit.WebView.setOverScrollMode(WebView.java:2247)
   at android.view.View.(View.java:3795)
   at android.view.View.(View.java:3909)
   at android.view.ViewGroup.(ViewGroup.java:507)
   at android.widget.AbsoluteLayout.(AbsoluteLayout.java:55)
   at android.webkit.WebView.(WebView.java:547)
   at android.webkit.WebView.(WebView.java:492)
   at android.webkit.WebView.(WebView.java:475)
   at android.webkit.WebView.(WebView.java:462)
   at java.lang.reflect.Constructor.newInstance(Constructor.java)
   at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
   at android.view.LayoutInflater.createView(LayoutInflater.java:614)
   at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55)
   at android.view.LayoutInflater.onCreateView(LayoutInflater.java:689)
   at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:748)
   at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
   at android.view.LayoutInflater.rInflate(LayoutInflater.java:821)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
   at com.tapmedia.tapito.WebViewFragment.onCreateView(SourceFile:84)
   at android.support.v4.app.Fragment.performCreateView(SourceFile:1789)
   at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:924)
   at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1116)
   at android.support.v4.app.FragmentManagerImpl.onCreateView(SourceFile:2196)
   at android.support.v4.app.FragmentActivity.onCreateView(SourceFile:300)
   at android.support.v7.app.AppCompatDelegateImplV7.callActivityOnCreateView(SourceFile:838)
   at android.support.v7.app.AppCompatDelegateImplV11.callActivityOnCreateView(SourceFile:34)
   at android.support.v7.app.AppCompatDelegateImplV7.onCreateView(SourceFile:826)
   at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(SourceFile:44)
   at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:732)
   at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:366)
   at android.support.v7.app.AppCompatDelegateImplV7.setContentView(SourceFile:249)
   at android.support.v7.app.AppCompatActivity.setContentView(SourceFile:106)
   at com.tapmedia.tapito.LockscreenActivity.onCreate(SourceFile:103)
   at android.app.Activity.performCreate(Activity.java:6289)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2647)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2759)
   at android.app.ActivityThread.access$900(ActivityThread.java:178)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:145)
   at android.app.ActivityThread.main(ActivityThread.java:5944)
   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:1399)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)

我不明白什么是错的。因为这个错误来自在线报告工具(Crashlytics / Fabric),我无法判断,每当特定用户尝试使用该片段时是否会发生这种情况,或者如果用户通常将片段膨胀并且错误仅发生在不时。 WebView小部件是系统的一部分,对吧?我的意思是 - 我不能在我的制作APK中丢失一些东西 - 比如支持库。或者我可以吗?

5 个答案:

答案 0 :(得分:65)

如果您从运行Android Lollipop的设备上看到这些报告,请忽略它们。当WebView软件包正在由Play商店更新(当前只能在Lollipop上发生)时,每当有人启动使用WebView的活动时,就会发生这种情况。在更新期间,程序包将被视为程序包管理器未安装。也就是说,您的应用没有任何问题。更新的软件包被认为不存在的时间窗口通常很小,因此当应用程序在崩溃后重新启动时,它将正常启动。

答案 1 :(得分:13)

要解决Android Lollipop上出现的此问题,您可以使用仅在Android Lollipop(API 21和22)上创建新配置的自定义WebView。使用此自定义WebView替换XML布局上的WebView。

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.util.AttributeSet;
import android.webkit.WebView;

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

    // To fix Android Lollipop WebView problem create a new configuration on that Android version only
    private static Context getFixedContext(Context context) {
        if (Build.VERSION.SDK_INT == 21 || Build.VERSION.SDK_INT == 22) // Android Lollipop 5.0 & 5.1
            return context.createConfigurationContext(new Configuration());
        return context;
    }
}

答案 2 :(得分:7)

如果您不依赖于新的Material DayNight主题切换(或其他UiMode事件),则可以将android:configChanges="uiMode"添加到Webview 活动清单,以防止AppCompatDelegate更新资源配置,从而防止更新弄乱了网络视图的通货膨胀。

答案 3 :(得分:3)

我在2020年也遇到了这个问题,现在有一个解决方案:

只需添加以下新依赖项:

implementation 'androidx.appcompat:appcompat:1.2.0-beta01'
implementation 'androidx.appcompat:appcompat-resources:1.2.0-beta01'

documentation说:

修复了androidx.appcompat:appcompat:1.1.0崩溃的问题 长按webview时的webview(b / 141351441)

答案 4 :(得分:0)

  

在使UI中的Webview膨胀的活动的onCreate中,您可以   可以尝试捕获以使自己免受错误产生的影响   速成游戏。

  /**
     * This element touches the UI elements
     * of the application and set them up.
     */
   try {
        setContentView(R.layout.activity_main);
        // ... further setup
    } catch (Exception ex) {
        transferToNoPackageFoundActivity(ex.getMessage());
    }


    private void transferToNoPackageFoundActivity(String errorMessage) {
        Intent intent = new Intent(this, NoPackageFoundActivity.class);
        intent.putExtra(Intent.EXTRA_INTENT, errorMessage);
        startActivity(intent);
        finish();
    }

在NoPackageFoundActivity中,您可以将用户带到Playstore下载Webview软件包。

    /**
 * This field is used for presenting the user
 * with an error image for no connectivity.
 */
private lateinit var mErrorImage: ImageView

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_no_network)
    // get the intent for the error message, if any.
    val intent: Intent = intent
    if (intent.hasExtra(Intent.EXTRA_INTENT)) {
        println(intent.getStringExtra(Intent.EXTRA_INTENT))
    }

    mErrorImage = findViewById(R.id.error_image)
    mErrorImage.contentDescription = resources.getString(R.string.no_network_image_desc)
    Glide.with(this)
            .load(R.drawable.ic_no_web_view_illustration)
            .into(mErrorImage)

    val enableButton = findViewById<Button>(R.id.error_handler_btn)
    enableButton.setOnClickListener { openGooglePlayStore() }
    enableButton.text = resources.getString(R.string.no_package_btn_text)

    val reloadText = findViewById<TextView>(R.id.no_network_reload)
    reloadText.setOnClickListener { reloadApplication() }

    val errorHeadingText = findViewById<TextView>(R.id.error_heading)
    val errorSubheadingText = findViewById<TextView>(R.id.error_subheading)
    errorHeadingText.text = resources.getString(R.string.no_package_heading_text)
    errorSubheadingText.text = resources.getString(R.string.no_package_subheading_text)
}

/**
 * This is a onClickListener Handler that
 * reloads the application when the user
 * clicks on it.
 * It starts the activity again from
 */
private fun reloadApplication() {
    val intent = Intent(this, SplashScreen::class.java)
    startActivity(intent)
    finish()
}

private fun openGooglePlayStore() {
    // you can also use BuildConfig.APPLICATION_ID
    val appId = "com.google.android.webview"
    val rateIntent = Intent(Intent.ACTION_VIEW,
            Uri.parse("market://details?id=$appId"))
    var marketFound = false
    // find all applications able to handle our rateIntent
    val otherApps = packageManager
            .queryIntentActivities(rateIntent, 0)
    for (otherApp in otherApps) { // look for Google Play application
        if (otherApp.activityInfo.applicationInfo.packageName
                == "com.android.vending") {
            val otherAppActivity = otherApp.activityInfo
            val componentName = ComponentName(
                    otherAppActivity.applicationInfo.packageName,
                    otherAppActivity.name
            )
            // make sure it does NOT open in the stack of your activity
            rateIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            // task reparenting if needed
            rateIntent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
            // if the Google Play was already open in a search result
            //  this make sure it still go to the app page you requested
            rateIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
            // this make sure only the Google Play app is allowed to
            // intercept the intent
            rateIntent.component = componentName
            startActivity(rateIntent)
            marketFound = true
            break
        }
    }
    // if GP not present on device, open web browser
    if (!marketFound) {
        val webIntent = Intent(Intent.ACTION_VIEW,
                Uri.parse("https://play.google.com/store/apps/details?id=$appId"))
        startActivity(webIntent)
    }
}