對於此問題的發生原因及解決方案,此處就不再贅述了。可以修改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(); } }