对于此问题的发生原因及解决方案,此处就不再赘述了。可以修改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(); } }