176 lines
6.3 KiB
Java
176 lines
6.3 KiB
Java
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);
|
||
}
|
||
}
|
||
}
|
||
|