If you use androidx.appcompat:appcompat:1.1.0, try androidx.appcompat:appcompat:1.0.2 instead.
it seems that 1.1.0 doesn't fix the bug with WebView in Android 5.1.1.
Feb-2020 update: Reverting to 1.0.2 stopped working for many people (including my app), but using the current version of androidx.appcompat:appcompat:1.2.0-alpha02 did fix the crash. (I was seeing it on a Huawei P8 Lite running Android 5.0 during Google's automated "Pre-launch report" testing).
Jun-2020 update: There are newer releases available than the one mentioned in the Feb-2020 update, you can see the currently available versions here:
If you are using androidx.appcompat:appcompat:1.1.0 and don't want to downgrade to androidx.appcompat:appcompat:1.0.2 or upgrading to androidx.appcompat:appcompat:1.2.0-alpha03, there's another solution which is described in this comment on the Google Issue Tracker.
I noticed that after calling applyOverrideConfiguration,
Context.getAssets()andContext.getResources().getAssets()are not returning the same AssetManager object. The AssetManager returned fromContext.getAssets()can't access resources in other packages (including the system WebView package), causing WebView to crash. If I overrideContext.getAssets()to returngetResources().getAssets(), the problem is gone.
Based on that comment, you can override the getAssets() in the WebView's Activity so that it returns getResources().getAssets() instead to solve the issue.
Java
@Override
public AssetManager getAssets() {
return getResources().getAssets();
}
Kotlin
override fun getAssets(): AssetManager {
return resources.assets
}
Warning: this workaround might also break some things; see the comments for details
If you'd like to inflate the WebView from an XML layout, you can wrap it in a nice little subclass (based on ikostet's answer):
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);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(getFixedContext(context), attrs, defStyleAttr, defStyleRes);
}
public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr, boolean privateBrowsing) {
super(getFixedContext(context), attrs, defStyleAttr, privateBrowsing);
}
public static Context getFixedContext(Context context) {
return context.createConfigurationContext(new Configuration());
}
}
EDIT: now even nicer with Kotlin
class LollipopFixedWebView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
defStyleRes: Int = 0
) : WebView(context.createConfigurationContext(Configuration()), attrs, defStyleAttr, defStyleRes)
my advice is to use custom/new Configuration only when "original one" is causing problems, so on Lollipop only. @SpaceBizon code work well till Android 8.x, on 9 and Q (currenly beta) every select/dropdown press won't show AlertDialog picker, instead of that memory leak occurs... below fixed getFixedContext method with "iffed" proper version code
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);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(getFixedContext(context), attrs, defStyleAttr, defStyleRes);
}
private static Context getFixedContext(Context context) {
if (Build.VERSION.SDK_INT >= 21 && Build.VERSION.SDK_INT < 23) // Android Lollipop 5.0 & 5.1
return context.createConfigurationContext(new Configuration());
return context;
}
}
If you are using androidx.appcompat:appcompat:1.1.0, either change to androidx.appcompat:appcompat:1.0.2 or if you want to use DayNight Theme, override applyOverrideConfiguration in your activity as follows. (Note: This requires app restart while switching from Dark Theme to Light Theme and vice versa).
override fun applyOverrideConfiguration(overrideConfiguration: Configuration?) {
if (Build.VERSION.SDK_INT in 21..25 && (resources.configuration.uiMode == applicationContext.resources.configuration.uiMode)) {
return
}
super.applyOverrideConfiguration(overrideConfiguration)
}
If you are not relying on DayNight theme switching (or other UiMode events), you can add android:configChanges="uiMode" to the webview activity manifest to prevent AppCompatDelegate updating the Resources configuration and thereby messing up the webview inflation.
Try use for creating webview:
mWebView = new WebView(getActivity().createConfigurationContext(new Configuration()));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With