For security reasons, WebView is
2024-07-18 本文已影响0人
程序猿老王
原因
在具有系统级权限的应用中使用 WebView 时,可能会遇到 java.lang.UnsupportedOperationException: For security reasons, WebView is not allowed in privileged processes 错误。这是因为出于安全考虑,Android 不允许在拥有系统权限的应用中使用 WebView。
解决方案
在setContentView之前调用以下hookWebView方法即可
const val TAG = "hookWebView"
private fun hookWebView() {
val sdkInt = Build.VERSION.SDK_INT
try {
val factoryClass = Class.forName("android.webkit.WebViewFactory")
val field = factoryClass.getDeclaredField("sProviderInstance")
field.isAccessible = true
var sProviderInstance = field[null]
if (sProviderInstance != null) {
Log.i(TAG, "sProviderInstance isn't null")
return
}
val getProviderClassMethod = if (sdkInt > 22) {
factoryClass.getDeclaredMethod("getProviderClass")
} else if (sdkInt == 22) {
factoryClass.getDeclaredMethod("getFactoryClass")
} else {
Log.i(TAG, "Don't need to Hook WebView")
return
}
getProviderClassMethod.isAccessible = true
val factoryProviderClass = getProviderClassMethod.invoke(factoryClass) as Class<*>
val delegateClass = Class.forName("android.webkit.WebViewDelegate")
val delegateConstructor = delegateClass.getDeclaredConstructor()
delegateConstructor.isAccessible = true
if (sdkInt < 26) { //低于Android O版本
val providerConstructor = factoryProviderClass.getConstructor(delegateClass)
if (providerConstructor != null) {
providerConstructor.isAccessible = true
sProviderInstance = providerConstructor.newInstance(delegateConstructor.newInstance())
}
} else {
val chromiumMethodName = factoryClass.getDeclaredField("CHROMIUM_WEBVIEW_FACTORY_METHOD")
chromiumMethodName.isAccessible = true
var chromiumMethodNameStr = chromiumMethodName[null] as String
if (chromiumMethodNameStr == null) {
chromiumMethodNameStr = "create"
}
val staticFactory = factoryProviderClass.getMethod(chromiumMethodNameStr, delegateClass)
if (staticFactory != null) {
sProviderInstance = staticFactory.invoke(null, delegateConstructor.newInstance())
}
}
if (sProviderInstance != null) {
field["sProviderInstance"] = sProviderInstance
Log.i(TAG, "Hook success!")
} else {
Log.i(TAG, "Hook failed!")
}
} catch (e: Throwable) {
Log.w(TAG, e)
}
}