解決Android8.0以上系統應用打開webView報錯的問題

對於此問題的發生原因及解決方案,此處就不再贅述了。可以修改framework,但最簡單的辦法還是通過反射的方式繞過檢查(請自行評估風險)。但是網上很多代碼對新版本的安卓系統無效(會報WebViewDelegate類NoSuchMethodException,導致hook失敗),以下代碼可解決Android8.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();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章