programing

Android.view를 참조.Class Android를 부풀리는 동안 BulgeException 오류가 발생했습니다.Webkit.WebView

javaba 2022. 9. 16. 22:51
반응형

Android.view를 참조.Class Android를 부풀리는 동안 BulgeException 오류가 발생했습니다.Webkit.WebView

롤리팝(API 22)에서는 어플리케이션의 크래시가 발생할 때마다 웹뷰가 표시됩니다.이 이벤트와 관련하여 안드로이드 개발자 콘솔에서 크래시가 여러 번 발생했습니다.

Android 4, 6, 7에서 동작하는 것은 말할 필요도 없습니다.

스택 트레이스(이 투고 마지막에 투고)를 읽다 보면 뭔가 신경이 쓰인다.

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

ID가 없기 때문에 생성된 R.java를 검색해 보았습니다만, 시도해 볼 만한 가치가 있었습니다.

이 문제에 대한 구글 검색은 롤리팝이 웹뷰를 처리하는 방식과 관련이 있는 것 같습니다.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 , scriptsandroidx.appcompat:appcompat:1.0.2대신.인 것 같다1.1.0는 수정되지 않습니다.WebView Android 。5.1.1.

2월 갱신2020년 2월 갱신: 로로 to to로 1.0.2 앱을을 위해 했지만, 현재 의 '어플리케이션'을 하고 있습니다.androidx.appcompat:appcompat:1.2.0-alpha02(Google의 자동화된 "출시 전 보고서" 테스트 중에 Android 5.0을 실행하는 Huawei P8 Lite에서 이를 보았습니다.)

2020년 6월 갱신:2020년 2월 업데이트에 기재되어 있는 릴리스보다 새로운 릴리스가 있습니다.현재 이용 가능한 버전은 다음 URL에서 확인할 수 있습니다.

「 」를 사용하고 androidx.appcompat:appcompat:1.1.0다운그레이드 하고 싶지 않습니다.androidx.appcompat:appcompat:1.0.2 「」로 합니다.androidx.appcompat:appcompat:1.2.0-alpha03Google Issue Tracker의 코멘트에 설명되어 있는 다른 솔루션이 있습니다.

호출한 후 applyOverrideConfiguration을 한 것을 되었습니다.Context.getAssets() ★★★★★★★★★★★★★★★★★」Context.getResources().getAssets()자산관리자가 Asset Manager에서 되었습니다.Context.getAssets()다른 패키지(시스템 WebView패키지 포함)의 리소스에 액세스 할 수 없기 때문에 WebView가 크래시 됩니다.★★★을 Context.getAssets()getResources().getAssets()

코멘트에 해, 이 코멘트를 수 .getAssets()에서 WebView를 한다.getResources().getAssets()대신 문제를 해결합니다.

자바

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

코틀린

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

주의: 이 회피책으로 인해 몇 가지 문제가 발생할 수 있습니다.자세한 내용은 주석을 참조하십시오.

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)

내 조언은 맞춤/신규를 사용하는 것이다.Configuration'오리지널 원'이 문제를 일으킬 때만 롤리팝에서만 사용할 수 있습니다.@SpaceBizon 코드는 Android 8.x, 9 및 Q(곡선 베타)까지 올바르게 동작합니다.선택/드롭다운을 누를 때마다 표시되지 않습니다.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 Theme를 사용하는 경우 다음과 같이 액티비티에서 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 이벤트)에 의존하지 않는 경우 Android:configChanges="uiMode"를 웹뷰 활동 매니페스트에 추가하여 AppCompatDelegate가 리소스 구성을 업데이트하여 웹뷰 인플레이션을 망치는 것을 방지할 수 있습니다.

웹 뷰 작성에 사용해보십시오.

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

그리고 문제를 해결하려고 한 번 더 시도하세요.액티비티에서 이 메서드를 덮어씁니다.

    @Override
    public void applyOverrideConfiguration(final Configuration overrideConfiguration) {
        if (Build.VERSION.SDK_INT >= 21 && Build.VERSION.SDK_INT < 25) {
            overrideConfiguration.uiMode &= ~Configuration.UI_MODE_NIGHT_MASK;
        }
        super.applyOverrideConfiguration(overrideConfiguration);
    }

에뮬레이터에서 API 21의 크래시를 재현할 수 있었습니다.

그래서 문서 설명에 따라 구현에 추가하려고 했습니다.

dependencies {
    def appcompat_version = "1.1.0"

    implementation "androidx.appcompat:appcompat:$appcompat_version"
    // For loading and tinting drawables on older versions of the platform
    implementation "androidx.appcompat:appcompat-resources:$appcompat_version"
}

추가 중appcompat-resources문제는 해결되지 않았다.

향후 버전이 될 수도 있지만, 이 문제를 해결하기 위한 보완적인 리소스 라이브러리가 있는 것 같습니다.이 문제를 해결하기 위해 새로운 버전의appcompat, 를 추가합니다.appcompat-resources같은 버전의 라이브러리입니다.

로 되돌아가다androidx.appcompat:appcompat:1.0.2회피책으로 이 문제를 해결했습니다.

다음 코드를 사용하면 문제가 해결됩니다.에 추가해 주세요.Activity:

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

는 이 출처의 최신 버전을 사용했습니다.자신이 가장 좋다고 생각하는 것을 확인하고 사용하세요.

건너뛸 경우 다음 구현으로 문제를 해결합니다.

implementation 'androidx.appcompat:appcompat:1.2.0'

덧붙여서, 1.0.2로 다운그레이드했는데, 단지 appcompat:1.1.0과 appcompat:1.0, restraintlayout:2.0.0-beta3에 대한 과도적 의존관계가 있는 것 같아서 잠시 고민했습니다.그것을 contraint layout: 1.1.3으로 다운그레이드 하면 모든 것이 정상적으로 동작합니다.

(https://issuetracker.google.com/issues/141351441에 따르면 appcompat: 1.2.0-alpha02에서 곧 문제가 수정될 예정입니다.)

★★★★★★★★★★★★★★★★★★★★그러나 Androidx.appcompat:appcompat:1.1.0에서 1.0.2로의 다운그레이드만 성공하지 못했습니다.

이전에 업그레이드된 모든 Androidx 버전을 에서 다운그레이드했습니다.

implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.android.material:material:1.1.0-alpha10'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.1.0-beta04'
implementation 'androidx.viewpager2:viewpager2:1.0.0-beta04'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
implementation 'androidx.preference:preference:1.1.0'
implementation 'androidx.core:core:1.2.0-alpha04'

로 되돌아가다.

implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.android.material:material:1.1.0-alpha09'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.1.0-beta03'
implementation 'androidx.viewpager2:viewpager2:1.0.0-beta03'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.vectordrawable:vectordrawable:1.1.0-rc01'
implementation 'androidx.preference:preference:1.1.0-rc01'
implementation 'androidx.core:core:1.2.0-alpha03'

구글 코드는 버그 프리도 아니고 테스트도 잘 되어 있지 않기 때문에 버전 업그레이드를 경솔하게 해서는 안 된다는 것을 상기시켜 줍니다.

/**
 * Customized WebView to avoid crashing on Android 5 and 6 (API level 21 to 23)
 * If the Android System WebView is old and is not updated, the WebView view inflation fails.
 * To reproduce the issue, try on OS 5 or 6 with Android System WebView 72.0.3626.76 (this version is just a reference point from being which we saw no crashes)
 */
class BrilliantWebView : WebView {

   companion object {
       private fun getBrilliantContext(context: Context?) =
            if (!OSUtils.hasNougat()) // OS < 24 or OS < 7.0
                context?.createConfigurationContext(Configuration())
            else
                context
    }

   constructor(context: Context?) : super(getBrilliantContext(context))
   constructor(context: Context?, attrs: AttributeSet?) : super(getBrilliantContext(context), attrs)
   constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(getBrilliantContext(context), attrs, defStyleAttr)
}

AppCompat 1.2.0-alpha02가 오늘 출시되었으므로

implementation 'androidx.appcompat:appcompat:1.2.0-alpha02'

그러면 롤리팝의 WebView 문제가 해결됩니다.

Nexus 7 API 22에서 이 문제를 재현할 수 있었습니다.이 문제는 태블릿의 Android System WebView 버전을 버전 39(2237560-arm)에서 버전 79.0.3945.136으로 업데이트하여 해결되었습니다.

이것은 사용자가 이것을 할 수 있는 것은 아니지만, 다른 사람이 당신의 앱을 즉시 사용할 수 있도록 도와줄 필요가 있는 경우에는 해결책입니다.

이 문제는 'androidx.appcompat:appcompat:1.0.2' 구현으로 다운그레이드하여 해결되었습니다.

내 경우 방식에 문제가 있었다.

fun getUserId(): Int = userId

왜 영향을 미치는지 WebViewgetUserId()덮어쓰지도 않고, 공개 방식도 아닙니다.Activity하면 class. 이 메서드의 이름을 바꾸거나 삭제하면WebView열리기 시작합니다. 변화를 .

private var userId: Int = 0

로.

var userId: Int = 0
    private set

같은 예외로 이어집니다.나는 예외를 발견했을 때 다음과 같이 이해했다.Caused by: java.lang.SecurityException: Permission Denial: null asks to run as user 123456 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL or android.permission.INTERACT_ACROSS_USERS 경우 로 내 user=123456이 WebView는 Android를 하고 있는 것 userId"user_id" "user_id" "user_id"

다른 많은 사람들이 알아챘듯이appcompat:1.1.0 ★★★★★★★★★★★★★★★★★」1.0.2 extend and를 확장하다WebViewclass.에서는 이 Google Play Services가 됩니다.WebView텍스트 라벨을 길게 터치하면 크래시 됩니다만, 일반적인 디바이스에서는 문제가 없습니다.

의존관계 버전을 변경하는 대신 솔루션으로서 프로그램적으로 webView 생성을 구현했습니다.

이 문제는 실제로는 xml 파일에서 레이아웃을 읽는 것부터 시작됩니다.따라서 프로그램 방식이 적용 가능한 솔루션이라면 아래 샘플을 확인하시기 바랍니다.

private WebView generateWebView(){
    WebView wv = new WebView(YourContext);
    wv.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    wv.setFitsSystemWindows(false); // your preferences
    wv.setVerticalScrollBarEnabled(false); // your preferences
    wv.setPadding(15,15,15,15); // your preferences
    return wv;
}

부모 뷰에 추가하는 것 이상의 기능:

LinearLayout scrollContainer = findViewById(R.id.scrollContainer);
scrollContainer.addView(generateWebView());

버전을 확인합니다.Androidx 앱호환과 Google 자료 버전은 항상 동일하게 유지됩니다.

implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation "androidx.cardview:cardview:1.0.0"

여기에 이미지 설명 입력

언급URL : https://stackoverflow.com/questions/41025200/android-view-inflateexception-error-inflating-class-android-webkit-webview

반응형