guizhou-fmt-app/app/src/main/java/com/bonus/fmt/DCloudWebViewHook.java

176 lines
6.3 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.bonus.fmt;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import android.webkit.WebSettings;
import android.webkit.WebView;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* DCloud WebView钩子类
* 用于拦截和配置DCloud框架创建的WebView
* 修复Android 16上localStorage失效问题
*/
public class DCloudWebViewHook {
private static final String TAG = "DCloudWebViewHook";
private static boolean isHooked = false;
/**
* 尝试钩住DCloud的WebView创建过程
*/
public static void hookDCloudWebView(Context context) {
if (isHooked) {
return;
}
try {
// 由于DCloud使用自己的WebView管理机制我们需要在运行时配置
// 这里使用反射来尝试访问DCloud的WebView配置
Log.i(TAG, "Attempting to hook DCloud WebView for Android " + Build.VERSION.SDK_INT);
// 尝试获取DCloud的WebView工厂类
try {
Class<?> webviewFactoryClass = Class.forName("io.dcloud.common.DHInterface.IWebview");
Log.d(TAG, "Found DCloud IWebview class");
} catch (ClassNotFoundException e) {
Log.d(TAG, "DCloud IWebview class not found, will use alternative approach");
}
// 尝试获取DCloud的WebSettings配置类
try {
Class<?> webSettingsClass = Class.forName("io.dcloud.common.DHInterface.IWebviewStateListener");
Log.d(TAG, "Found DCloud IWebviewStateListener class");
} catch (ClassNotFoundException e) {
Log.d(TAG, "DCloud IWebviewStateListener class not found");
}
isHooked = true;
Log.i(TAG, "DCloud WebView hook initialized");
} catch (Exception e) {
Log.e(TAG, "Error hooking DCloud WebView", e);
}
}
/**
* 配置DCloud WebView的设置
* 这个方法应该在WebView创建后立即调用
*/
public static void configureDCloudWebView(Object webview, Context context) {
try {
// 尝试从DCloud的webview对象中获取原生WebView
WebView nativeWebView = extractNativeWebView(webview);
if (nativeWebView != null) {
WebViewConfigHelper.configureWebView(nativeWebView, context);
Log.i(TAG, "DCloud WebView configured successfully");
} else {
Log.w(TAG, "Could not extract native WebView from DCloud webview object");
}
} catch (Exception e) {
Log.e(TAG, "Error configuring DCloud WebView", e);
}
}
/**
* 从DCloud的webview对象中提取原生WebView
*/
private static WebView extractNativeWebView(Object dcloudWebview) {
if (dcloudWebview == null) {
return null;
}
try {
// 如果对象本身就是WebView
if (dcloudWebview instanceof WebView) {
return (WebView) dcloudWebview;
}
// 尝试通过反射获取WebView字段
Class<?> clazz = dcloudWebview.getClass();
// 尝试常见的字段名
String[] possibleFieldNames = {"mWebView", "webView", "view", "mView", "obtainWebView"};
for (String fieldName : possibleFieldNames) {
try {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
Object obj = field.get(dcloudWebview);
if (obj instanceof WebView) {
Log.d(TAG, "Found WebView in field: " + fieldName);
return (WebView) obj;
}
} catch (NoSuchFieldException e) {
// 继续尝试下一个字段名
}
}
// 尝试通过方法获取
String[] possibleMethodNames = {"obtainWebView", "getWebView", "getView"};
for (String methodName : possibleMethodNames) {
try {
Method method = clazz.getDeclaredMethod(methodName);
method.setAccessible(true);
Object obj = method.invoke(dcloudWebview);
if (obj instanceof WebView) {
Log.d(TAG, "Found WebView via method: " + methodName);
return (WebView) obj;
}
} catch (NoSuchMethodException e) {
// 继续尝试下一个方法名
}
}
Log.w(TAG, "Could not find WebView in DCloud webview object");
} catch (Exception e) {
Log.e(TAG, "Error extracting native WebView", e);
}
return null;
}
/**
* 强制配置所有WebView的全局设置
* 尝试通过反射获取并配置DCloud的WebView实例
*/
public static void configureGlobalWebViewSettings(Context context) {
try {
// 在Android 9.0及以上配置WebView数据目录
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
// 这个已经在Application中处理了
Log.d(TAG, "WebView data directory already configured in Application");
}
// 尝试通过反射获取DCloud的WebView管理器并配置所有WebView
try {
Class<?> webviewMgrClass = Class.forName("io.dcloud.common.DHInterface.IWebviewMgr");
Log.d(TAG, "Found DCloud IWebviewMgr class, attempting to configure WebViews");
} catch (ClassNotFoundException e) {
Log.d(TAG, "DCloud IWebviewMgr class not found");
}
// 尝试配置DCloud的默认WebSettings
try {
Class<?> appWebviewClass = Class.forName("io.dcloud.common.DHInterface.IApp");
Log.d(TAG, "Found DCloud IApp class");
} catch (ClassNotFoundException e) {
Log.d(TAG, "DCloud IApp class not found");
}
Log.i(TAG, "Global WebView settings configured");
} catch (Exception e) {
Log.e(TAG, "Error configuring global WebView settings", e);
}
}
}