[java] android.view.InflateException 클래스 android.webkit.WebView 팽창 오류

Lollipop (API 22)에서는 애플리케이션에서 매번 애플리케이션 충돌이 발생하는 웹뷰를 보여줍니다. 이 이벤트와 관련된 Android 개발자 콘솔에 여러 충돌이 있습니다.

Android 4, 6 및 7에서 작동한다고 말할 필요가 없습니다.

스택 추적 읽기 (이 게시물 끝에 게시 됨), 뭔가 버그가 있습니다.

Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x2040003

나는 ID가 존재하지 않기 때문에 운없이 생성 된 R.java에서 검색했지만 시도해 볼 가치가있었습니다.

문제를 검색하는 것은 Lollipop이 웹뷰를 처리하는 방법과 관련이있는 것 같습니다. GDC의 크래시 리포터에서 찾은 장치를 기반으로 롤리팝으로 새로운 AVD를 시작했고 문제를 재현 할 수 있습니다.


전체 스택 추적 :

android.view.InflateException: Binary XML file line #7: Error inflating class android.webkit.WebView
                  at android.view.LayoutInflater.createView(LayoutInflater.java:633)
                  at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55)
                  at android.view.LayoutInflater.onCreateView(LayoutInflater.java:682)
                  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:741)
                  at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
                  at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
                  at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
                  at it.artecoop.ibreviary.WebViewFragment.onCreateView(WebViewFragment.java:67)
                  at android.support.v4.app.Fragment.performCreateView(Fragment.java:2087)
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1113)
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1295)
                  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801)
                  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1682)
                  at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:541)
                  at android.os.Handler.handleCallback(Handler.java:739)
                  at android.os.Handler.dispatchMessage(Handler.java:95)
                  at android.os.Looper.loop(Looper.java:135)
                  at android.app.ActivityThread.main(ActivityThread.java:5254)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at java.lang.reflect.Method.invoke(Method.java:372)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
               Caused by: java.lang.reflect.InvocationTargetException
                  at java.lang.reflect.Constructor.newInstance(Native Method)
                  at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
                  at android.view.LayoutInflater.createView(LayoutInflater.java:607)
                  at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55) 
                  at android.view.LayoutInflater.onCreateView(LayoutInflater.java:682) 
                  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:741) 
                  at android.view.LayoutInflater.rInflate(LayoutInflater.java:806) 
                  at android.view.LayoutInflater.inflate(LayoutInflater.java:504) 
                  at android.view.LayoutInflater.inflate(LayoutInflater.java:414) 
                  at it.artecoop.ibreviary.WebViewFragment.onCreateView(WebViewFragment.java:67) 
                  at android.support.v4.app.Fragment.performCreateView(Fragment.java:2087) 
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1113) 
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1295) 
                  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801) 
                  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1682) 
                  at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:541) 
                  at android.os.Handler.handleCallback(Handler.java:739) 
                  at android.os.Handler.dispatchMessage(Handler.java:95) 
                  at android.os.Looper.loop(Looper.java:135) 
                  at android.app.ActivityThread.main(ActivityThread.java:5254) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at java.lang.reflect.Method.invoke(Method.java:372) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 
               Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x2040003
                  at android.content.res.Resources.getText(Resources.java:299)
                  at android.content.res.Resources.getString(Resources.java:385)
                  at com.android.org.chromium.content.browser.ContentViewCore.setContainerView(ContentViewCore.java:684)
                  at com.android.org.chromium.content.browser.ContentViewCore.initialize(ContentViewCore.java:608)
                  at com.android.org.chromium.android_webview.AwContents.createAndInitializeContentViewCore(AwContents.java:631)
                  at com.android.org.chromium.android_webview.AwContents.setNewAwContents(AwContents.java:780)
                  at com.android.org.chromium.android_webview.AwContents.<init>(AwContents.java:619)
                  at com.android.org.chromium.android_webview.AwContents.<init>(AwContents.java:556)
                  at com.android.webview.chromium.WebViewChromium.initForReal(WebViewChromium.java:311)
                  at com.android.webview.chromium.WebViewChromium.access$100(WebViewChromium.java:96)
                  at com.android.webview.chromium.WebViewChromium$1.run(WebViewChromium.java:263)
                  at com.android.webview.chromium.WebViewChromium$WebViewChromiumRunQueue.drainQueue(WebViewChromium.java:123)
                  at com.android.webview.chromium.WebViewChromium$WebViewChromiumRunQueue$1.run(WebViewChromium.java:110)
                  at com.android.org.chromium.base.ThreadUtils.runOnUiThread(ThreadUtils.java:144)
                  at com.android.webview.chromium.WebViewChromium$WebViewChromiumRunQueue.addTask(WebViewChromium.java:107)
                  at com.android.webview.chromium.WebViewChromium.init(WebViewChromium.java:260)
                  at android.webkit.WebView.<init>(WebView.java:554)
                  at android.webkit.WebView.<init>(WebView.java:489)
                  at android.webkit.WebView.<init>(WebView.java:472)
                  at android.webkit.WebView.<init>(WebView.java:459)
                  at java.lang.reflect.Constructor.newInstance(Native Method) 
                  at java.lang.reflect.Constructor.newInstance(Constructor.java:288) 
                  at android.view.LayoutInflater.createView(LayoutInflater.java:607) 
                  at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55) 
                  at android.view.LayoutInflater.onCreateView(LayoutInflater.java:682) 
                  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:741) 
                  at android.view.LayoutInflater.rInflate(LayoutInflater.java:806) 
                  at android.view.LayoutInflater.inflate(LayoutInflater.java:504) 
                  at android.view.LayoutInflater.inflate(LayoutInflater.java:414) 
                  at it.artecoop.ibreviary.WebViewFragment.onCreateView(WebViewFragment.java:67) 
                  at android.support.v4.app.Fragment.performCreateView(Fragment.java:2087) 
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1113) 
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1295) 
                  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801) 
                  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1682) 
                  at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:541) 
                  at android.os.Handler.handleCallback(Handler.java:739) 
                  at android.os.Handler.dispatchMessage(Handler.java:95) 
                  at android.os.Looper.loop(Looper.java:135) 
                  at android.app.ActivityThread.main(ActivityThread.java:5254) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at java.lang.reflect.Method.invoke(Method.java:372) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 



답변

을 사용하는 경우 대신 androidx.appcompat:appcompat:1.1.0시도하십시오 androidx.appcompat:appcompat:1.0.2. Android 1.1.0에서 버그를 수정하지 않는 것 같습니다 .WebView5.1.1

2020 년 2 월 업데이트 : 1.0.2많은 사람들 (내 앱 포함)의 작동 을 중지 하도록 되돌 렸지만의 현재 버전을 사용 androidx.appcompat:appcompat:1.2.0-alpha02하면 충돌이 해결되었습니다. (Google의 자동화 된 “사전 출시 보고서”테스트 중에 Android 5.0을 실행하는 Huawei P8 Lite에서이를 확인했습니다.)

2020 년 6 월 업데이트 : 2020 년 2 월 업데이트에 언급 된 것보다 더 새로운 릴리스가 있습니다. 여기에서 현재 사용 가능한 버전을 확인할 수 있습니다.


답변

경고 :이 해결 방법으로 인해 일부 문제가 발생할 수도 있습니다. 자세한 내용은 주석을 참조하십시오.

XML 레이아웃에서 WebView를 확장하려면 ikostet의 답변 에 따라 멋진 작은 하위 클래스로 래핑 할 수 있습니다 .

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

편집 : 이제 Kotlin으로 더 멋지게

class LollipopFixedWebView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
    defStyleRes: Int = 0
) : WebView(context.createConfigurationContext(Configuration()), attrs, defStyleAttr, defStyleRes)


답변

을 사용 androidx.appcompat:appcompat:1.1.0중이고로 다운 그레이드 androidx.appcompat:appcompat:1.0.2하거나로 업그레이드 하지 않으려 androidx.appcompat:appcompat:1.2.0-alpha03는 경우 Google Issue Tracker 의이 주석 에 설명 된 다른 솔루션 있습니다.

나는 applyOverrideConfiguration를 호출 한 후 그 눈치 Context.getAssets()Context.getResources().getAssets()같은 AssetManager 개체를 반환하지 않습니다. 에서 반환 된 AssetManager는 Context.getAssets()다른 패키지 (시스템 WebView 패키지 포함)의 리소스에 액세스 할 수 없으므로 WebView가 충돌합니다. Context.getAssets()반환하도록 재정의 getResources().getAssets()하면 문제가 사라집니다.

해당 주석을 기반으로 getAssets()WebView의 활동에서을 재정 getResources().getAssets()의하여 문제를 해결하기 위해 대신 반환되도록 할 수 있습니다 .

자바

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

Kotlin

override fun getAssets(): AssetManager {
    return resources.assets
}


답변

내 조언은 Configuration“원본”이 문제를 일으킬 때만 사용자 지정 / 새로 만들기를 사용하는 것이므로 Lollipop에서만 사용할 수 있습니다. (9) Q (currenly 베타) 표시되지마다 선택 / 드롭 눌러 잘 안드로이드 8.x 사용까지 @SpaceBizon 코드 일, AlertDialog선택기, 즉 메모리 누수가 발생하는 대신 … 아래 고정 getFixedContext“iffed”적절한 버전 코드와 방법

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


답변

androidx.appcompat : appcompat : 1.1.0을 사용하는 경우 androidx.appcompat : appcompat : 1.0.2로 변경하거나 DayNight 테마를 사용하려면 다음과 같이 활동에서 applyOverrideConfiguration을 재정의합니다. (참고 : 어두운 테마에서 밝은 테마로 또는 그 반대로 전환하는 동안 앱을 다시 시작해야합니다).

override fun applyOverrideConfiguration(overrideConfiguration: Configuration?) {
        if (Build.VERSION.SDK_INT in 21..25 && (resources.configuration.uiMode ==  applicationContext.resources.configuration.uiMode)) {
                return
        }
        super.applyOverrideConfiguration(overrideConfiguration)
}


답변

DayNight 테마 전환 (또는 기타 UiMode 이벤트)에 의존하지 않는 경우 webview 활동 매니페스트에 android : configChanges = “uiMode” 를 추가하여 AppCompatDelegate가 리소스 구성을 업데이트하여 웹뷰 인플레이션을 엉망으로 만들 수 있습니다.


답변

webview를 만드는 데 사용해보십시오.

mWebView = new WebView(getActivity().createConfigurationContext(new Configuration()));