解决 Android 系统应用无法使用WebView的问题
程序员文章站
2022-08-17 13:08:54
在 android 8.0 系统上,普通应用使用 WebView 时,正常使用没问题。如果是系统级应用,就会报错java.lang.UnsupportedOperationException: For security reasons, WebView is not allowed in privileged processes解决办法有:1.使用 hookWebView() 方法欺骗系统;2.修改源代码;一.使用 hookWebView() 方法欺骗系统;使用 hookWebView()...
在 android 8.0 系统上,普通应用使用 WebView 时,正常使用没问题。
如果是系统级应用,就会报错
java.lang.UnsupportedOperationException: For security reasons, WebView is not allowed in privileged processes
解决办法有:
1.使用 hookWebView()
方法欺骗系统;
2.修改源代码;
一.使用 hookWebView()
方法欺骗系统;
- 使用
hookWebView()
方法欺骗系统,然后在应用的Application
的onCreate()
里调用此方法。
/**
* 给WebViewFactory sProviderInstance赋值,避免进行进程判断而抛出异常(系统应用不能使用WebView)
*/
@SuppressWarnings("unchecked")
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);
}
}
2.我已经这样改了,又有新问题出现了。
在 Setting 应用中添加,提示 xxxx (具体的报错忘了);
删除 AndroidManifest.xml
文件里的 android:defaultToDeviceProtectedStorage="true"
。
测试之后发现,不用在 Application
里调用 hookWebView()
方法,
在使用 WebView
的 Activity
里调用也会生效。
二.修改源代码
搜索异常提示 "For security reasons, WebView is not allowed in privileged processes"
得知,
是在 frameworks/base/core/java/android/webkit/WebViewFactory.java
的static WebViewFactoryProvider getProvider() {}
方法中抛出的,
static WebViewFactoryProvider getProvider() {
synchronized (sProviderLock) {
// For now the main purpose of this function (and the factory abstraction) is to keep
// us honest and minimize usage of WebView internals when binding the proxy.
if (sProviderInstance != null) return sProviderInstance;
final int uid = android.os.Process.myUid();
if (uid == android.os.Process.ROOT_UID || uid == android.os.Process.SYSTEM_UID
|| uid == android.os.Process.PHONE_UID || uid == android.os.Process.NFC_UID
|| uid == android.os.Process.BLUETOOTH_UID) {
throw new UnsupportedOperationException(
"For security reasons, WebView is not allowed in privileged processes");
}
//省略其余代码
}
}
将该异常注释即可,当然,这样做不太好,谨慎。
本文地址:https://blog.csdn.net/weixin_44021334/article/details/107496721
推荐阅读
-
Android 中TextView的使用imageview被压缩问题解决办法
-
解决webView无法播放视频的问题
-
Centos系统下“无法打开并写入文件”问题的解决
-
如何安装ubuntu双系统与一些问题解决(4.解决亮度无法调节的问题)
-
解决Pycharm无法使用已经安装Selenium的问题
-
在iOS10系统中微信后退无法发起ajax请求的问题解决办法
-
解决Android从相册中获取图片出错图片却无法裁剪问题的方法
-
java在linux系统下开机启动无法使用sudo命令的原因及解决办法
-
详解 Android中Libgdx使用ShapeRenderer自定义Actor解决无法接收到Touch事件的问题
-
Android 解决WebView调用loadData()方法显示乱码的问题