안드로이드 8 해결0 이상 시스템 응용 프로그램에서 웹 뷰를 켜면 오류가 발생합니다

2957 단어 시스템 응용
이 문제의 발생 원인과 해결 방안에 대해서는 더 이상 군말하지 않겠다.프레임워크를 수정할 수 있지만 가장 간단한 방법은 반사적인 방식으로 검사를 빙빙 돌려서 하는 것이다. (스스로 위험을 평가하십시오.)그러나 인터넷의 많은 코드가 새 버전의 안드로이드 시스템에 무효(WebView Delegate 클래스 NoSuch Method Exception에 보고하여 hook에 실패함)입니다. 다음 코드는 안드로이드 8.0 이상의 시스템에서 발생한 문제(Android P 시스템은 유효한 실측)를 참조하십시오.
public static void hookWebView(){
    int sdkInt = Build.VERSION.SDK_INT;
    try {
        Class> factoryClass = Class.forName("android.webkit.WebViewFactory");
        Field field = factoryClass.getDeclaredField("sProviderInstance");
        field.setAccessible(true);
        Object sProviderInstance = field.get(null);
        if (sProviderInstance != null) {
            Log.i("hookWebView","sProviderInstance isn't null");
            return;
        }

        Method getProviderClassMethod;
        if (sdkInt > 22) {
            getProviderClassMethod = factoryClass.getDeclaredMethod("getProviderClass");
        } else if (sdkInt == 22) {
            getProviderClassMethod = factoryClass.getDeclaredMethod("getFactoryClass");
        } else {
            Log.i("hookWebView","Don't need to Hook WebView");
            return;
        }
        getProviderClassMethod.setAccessible(true);
        Class> factoryProviderClass = (Class>) getProviderClassMethod.invoke(factoryClass);
        Class> delegateClass = Class.forName("android.webkit.WebViewDelegate");
        Constructor> delegateConstructor = delegateClass.getDeclaredConstructor();
        delegateConstructor.setAccessible(true);
        if(sdkInt < 26){//  Android O  
            Constructor> providerConstructor = factoryProviderClass.getConstructor(delegateClass);
            if (providerConstructor != null) {
                providerConstructor.setAccessible(true);
                sProviderInstance = providerConstructor.newInstance(delegateConstructor.newInstance());
            }
        } else {
            Field chromiumMethodName = factoryClass.getDeclaredField("CHROMIUM_WEBVIEW_FACTORY_METHOD");
            chromiumMethodName.setAccessible(true);
            String chromiumMethodNameStr = (String)chromiumMethodName.get(null);
            if (chromiumMethodNameStr == null) {
                chromiumMethodNameStr = "create";
            }
            Method staticFactory = factoryProviderClass.getMethod(chromiumMethodNameStr, delegateClass);
            if (staticFactory!=null){
                sProviderInstance = staticFactory.invoke(null, delegateConstructor.newInstance());
            }
        }

        if (sProviderInstance != null){
            field.set("sProviderInstance", sProviderInstance);
            Log.i("hookWebView","Hook success!");
        } else {
            Log.i("hookWebView","Hook failed!");
        }
    } catch (Throwable e) {
        e.printStackTrace();
    }
}

좋은 웹페이지 즐겨찾기