룬아님의 취중코딩

androidx.appcompat:appcompat:1.1.0을 사용할 때 롤리팝 버전 WebView에서 crash가 발생하는 증상 본문

개발/안드로이드 개발

androidx.appcompat:appcompat:1.1.0을 사용할 때 롤리팝 버전 WebView에서 crash가 발생하는 증상

룬아님 2020. 2. 24. 13:47

 

android.view.InflateException: Binary XML file line #7: Error inflating class android.webkit.WebView

 

SDK 버전 21~22 롤리팝에서 최신 appcompat 버전을 사용하면 크래시가 발생하는 버그가 있다.
현재 1.2.0-alpha02 버전에서 크래시가 고쳐졌는데 알파 버전의 사용이 꺼려진다면 다음과 같은 방법을 사용한다.

 

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

이런식으로 웹뷰를 커스텀하여 해당 버전에서 context를 바꾸어 주는 것으로 크래시 해결은 가능하지만
웹뷰에서 캘린더나 dialog을 켜지 못하는 다른 버그가 발생했다.
context를 application context로 바꾸다 보니 뷰를 건드리지 못하여 발생하는 문제 같았다.

 

https://stackoverflow.com/a/59961940/12951267 

 

android.view.InflateException Error inflating class android.webkit.WebView

In Lollipop (API 22) every time in my application I show a webview the application crashes. I have multiple crashes in my android developer console related to this event. No need to say that it wo...

stackoverflow.com

하지만 다른 해결 방안에서 롤리팝에서 Context.getAssets()이 Context.getResources().getAssets()과 다른 asset을 리턴하는 것을 확인했고 Context.getAssets()이 다른 패키지에 있는 리소스에 접근하지 못하여 생기는 크래시라는 것을 알아냈다.

이를 해결하기 위해서는

@Override
public AssetManager getAssets() {
    return getResources().getAssets();
}

해당 함수를 override하여 getResources().getAssets()를 사용하도록 하면 해결된다.

반응형
Comments