设备环境:Android O , android:sharedUserId="android.uid.system" 进程
错误: android.view.InflateException: Binary XML file line #24: Error inflating class android.webkit.WebView。。。。
。。。For security reasons, WebView is not allowed in privileged processes
网上的解决办法:
1. manifest的Application下面添加:
<meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
android:value="true"/>
验证结果:然并卵
2. 在app文件下的build.gradle里面的appcompat版本如果是1.1.0的话webview会出错误,改成1.0.2
验证结果:然并卵
3. (效果同第4点)application属性增加: android:usesCleartextTraffic="true"
验证结果:然并卵 (非 android:sharedUserId="android.uid.system" 进程 有效)
4. (效果同第3点) application属性增加:android:networkSecurityConfig="@xml/network_security_config" res/xml/下面放置的network_security_config.xml 内容:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true" /> </network-security-config>
验证结果:然并卵 (非 android:sharedUserId="android.uid.system" 进程 有效)
5. 终极有效的解决方法: 在Application启动的时候先调用该方法 (同时要加上第3点或者第4点)
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(TAG,
"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(TAG,
"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(TAG,
"Hook success!"
);
}
else
{
Log.i(TAG,
"Hook failed!"
);
}
}
catch
(Throwable e) {
Log.w(TAG,e);
}
}