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