Skip to content

Commit f5082f2

Browse files
committed
修复5.x上webview加载asset资源失败的问题
1 parent b25279c commit f5082f2

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

PluginCore/src/com/plugin/core/PluginLoader.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import android.content.res.Resources;
2424
import android.os.Build;
2525
import android.os.Bundle;
26+
import android.os.Handler;
2627
import android.text.TextUtils;
2728

2829
import com.plugin.content.PluginDescriptor;
@@ -35,6 +36,7 @@
3536
import com.plugin.core.systemservice.AndroidAppIActivityManager;
3637
import com.plugin.core.systemservice.AndroidAppINotificationManager;
3738
import com.plugin.core.systemservice.AndroidAppIPackageManager;
39+
import com.plugin.core.systemservice.AndroidWebkitWebViewFactoryProvider;
3840
import com.plugin.core.systemservice.AndroidWidgetToast;
3941
import com.plugin.util.LogUtil;
4042
import com.plugin.util.FileUtil;
@@ -88,6 +90,13 @@ public static synchronized void initLoader(Application app, PluginManager manage
8890
AndroidAppINotificationManager.installProxy();
8991
AndroidAppIPackageManager.installProxy(sApplication.getPackageManager());
9092
AndroidWidgetToast.installProxy();
93+
//不可在主进程中同步安装,因为此时ActivityThread还没有准备好, 会导致空指针。
94+
new Handler().postDelayed(new Runnable() {
95+
@Override
96+
public void run() {
97+
AndroidWebkitWebViewFactoryProvider.installProxy();
98+
}
99+
}, 50);
91100

92101
PluginInjector.injectInstrumentation();
93102
PluginInjector.injectHandlerCallback();
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package com.plugin.core.systemservice;
2+
3+
import android.content.Context;
4+
import android.os.Build;
5+
import android.webkit.WebView;
6+
7+
import com.plugin.core.proxy.MethodDelegate;
8+
import com.plugin.core.proxy.MethodProxy;
9+
import com.plugin.core.proxy.ProxyUtil;
10+
import com.plugin.util.LogUtil;
11+
import com.plugin.util.RefInvoker;
12+
13+
import java.lang.reflect.InvocationTargetException;
14+
import java.lang.reflect.Method;
15+
16+
/**
17+
* Created by cailiming on 16/1/28.
18+
*/
19+
public class AndroidWebkitWebViewFactoryProvider extends MethodProxy {
20+
21+
public static void installProxy() {
22+
if (Build.VERSION.SDK_INT >= 19) {
23+
LogUtil.d("安装WebViewFactoryProviderProxy");
24+
//在4。4及以上,这里的WebViewFactoryProvider的实际类型是
25+
// com.android.webview.chromium.WebViewChromiumFactoryProvider implements WebViewFactoryProvider
26+
Object webViewFactoryProvider = RefInvoker.invokeMethod(null, "android.webkit.WebViewFactory", "getProvider", (Class[]) null, (Object[]) null);
27+
Object webViewFactoryProviderProxy = ProxyUtil.createProxy(webViewFactoryProvider, new AndroidWebkitWebViewFactoryProvider());
28+
RefInvoker.setStaticOjbect("android.webkit.WebViewFactory", "sProviderInstance", webViewFactoryProviderProxy);
29+
LogUtil.d("安装完成");
30+
}
31+
}
32+
33+
static {
34+
sMethods.put("createWebView", new createWebView());
35+
}
36+
37+
public static class createWebView extends MethodDelegate {
38+
39+
@Override
40+
public Object afterInvoke(Object target, Method method, Object[] args, Object beforeInvoke, final Object invokeResult) {
41+
//这里invokeResult的实际类型是
42+
// com.android.webview.chromium.WebViewChromium implements WebViewProvider
43+
//所以这里可以再次进行Proxy
44+
final WebView webView = (WebView) args[0];
45+
return ProxyUtil.createProxy(invokeResult, new MethodDelegate() {
46+
47+
@Override
48+
public Object beforeInvoke(Object target, Method method, Object[] args) {
49+
fixWebViewAsset(webView.getContext());
50+
return super.beforeInvoke(target, method, args);
51+
}
52+
53+
});
54+
}
55+
}
56+
57+
private static void fixWebViewAsset(Context context) {
58+
try {
59+
if (sContentMain == null) {
60+
Object provider = RefInvoker.invokeMethod(null, "android.webkit.WebViewFactory", "getProvider", (Class[]) null, (Object[]) null);
61+
if (provider != null) {
62+
ClassLoader cl = provider.getClass().getClassLoader();
63+
64+
try {
65+
sContentMain = Class.forName("org.chromium.content.app.ContentMain", true, cl);
66+
} catch (ClassNotFoundException e) {
67+
}
68+
69+
if (sContentMain == null) {
70+
try {
71+
sContentMain = Class.forName("com.android.org.chromium.content.app.ContentMain", true, cl);
72+
} catch (ClassNotFoundException e) {
73+
}
74+
}
75+
76+
if (sContentMain == null) {
77+
throw new ClassNotFoundException(String.format("Can not found class %s or %s in classloader %s", "org.chromium.content.app.ContentMain", "com.android.org.chromium.content.app.ContentMain", cl));
78+
}
79+
}
80+
}
81+
if (sContentMain != null) {
82+
RefInvoker.invokeMethod(null, sContentMain, "initApplicationContext", new Class[]{Context.class}, new Object[]{context.getApplicationContext()});
83+
}
84+
} catch (Exception e) {
85+
LogUtil.printException("createWebview", e);
86+
}
87+
}
88+
89+
private static Class sContentMain;
90+
91+
}

0 commit comments

Comments
 (0)