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