4
4
import android .os .Build ;
5
5
import android .text .TextUtils ;
6
6
7
+ import com .elderdrivers .riru .edxp .config .ConfigManager ;
7
8
import com .elderdrivers .riru .edxp .core .yahfa .HookMain ;
8
9
import com .elderdrivers .riru .edxp .util .ProxyClassLoader ;
9
10
import com .elderdrivers .riru .edxp .yahfa .BuildConfig ;
26
27
import external .com .android .dx .Local ;
27
28
import external .com .android .dx .MethodId ;
28
29
import external .com .android .dx .TypeId ;
30
+ import pxb .android .arsc .Config ;
29
31
30
32
import static com .elderdrivers .riru .edxp .yahfa .dexmaker .DexMakerUtils .autoBoxIfNecessary ;
31
33
import static com .elderdrivers .riru .edxp .yahfa .dexmaker .DexMakerUtils .autoUnboxIfNecessary ;
34
+ import static com .elderdrivers .riru .edxp .yahfa .dexmaker .DexMakerUtils .canCache ;
32
35
import static com .elderdrivers .riru .edxp .yahfa .dexmaker .DexMakerUtils .createResultLocals ;
33
36
import static com .elderdrivers .riru .edxp .yahfa .dexmaker .DexMakerUtils .getObjTypeIdIfPrimitive ;
34
37
@@ -69,7 +72,6 @@ public class HookerDexMaker {
69
72
private Class <?> mHookClass ;
70
73
private Method mHookMethod ;
71
74
private Method mBackupMethod ;
72
- private String mDexDirPath ;
73
75
private EdHooker mHooker ;
74
76
75
77
private static TypeId <?>[] getParameterTypeIds (Class <?>[] parameterTypes , boolean isStatic ) {
@@ -101,7 +103,7 @@ private static Class<?>[] getParameterTypes(Class<?>[] parameterTypes, boolean i
101
103
}
102
104
103
105
public void start (Member member , XposedBridge .AdditionalHookInfo hookInfo ,
104
- ClassLoader appClassLoader , String dexDirPath ) throws Exception {
106
+ ClassLoader appClassLoader ) throws Exception {
105
107
if (member instanceof Method ) {
106
108
Method method = (Method ) member ;
107
109
mIsStatic = Modifier .isStatic (method .getModifiers ());
@@ -132,7 +134,6 @@ public void start(Member member, XposedBridge.AdditionalHookInfo hookInfo,
132
134
}
133
135
mMember = member ;
134
136
mHookInfo = hookInfo ;
135
- mDexDirPath = dexDirPath ;
136
137
if (appClassLoader == null
137
138
|| appClassLoader .getClass ().getName ().equals ("java.lang.BootClassLoader" )) {
138
139
mAppClassLoader = getClass ().getClassLoader ();
@@ -145,27 +146,36 @@ public void start(Member member, XposedBridge.AdditionalHookInfo hookInfo,
145
146
146
147
@ TargetApi (Build .VERSION_CODES .O )
147
148
private void doMake (String hookedClassName ) throws Exception {
148
- final boolean useInMemoryCl = TextUtils .isEmpty (mDexDirPath );
149
149
mDexMaker = new DexMaker ();
150
- ClassLoader loader ;
150
+ ClassLoader loader = null ;
151
151
// Generate a Hooker class.
152
152
String className = CLASS_NAME_PREFIX ;
153
- if (!useInMemoryCl ) {
154
- // if not using InMemoryDexClassLoader, className is also used as dex file name
155
- // so it should be different from each other
156
- String suffix = DexMakerUtils .getSha1Hex (mMember .toString ());
157
- if (TextUtils .isEmpty (suffix )) { // just in case
158
- suffix = String .valueOf (sClassNameSuffix .getAndIncrement ());
159
- }
160
- className = className + suffix ;
161
- if (!new File (mDexDirPath , className ).exists ()) {
162
- // if file exists, reuse it and skip generating
163
- doGenerate (className );
164
- }
165
- // load dex file from disk
166
- loader = mDexMaker .generateAndLoad (mAppClassLoader , new File (mDexDirPath ), className );
167
- } else {
153
+ boolean usedCache = false ;
154
+ if (canCache ) {
155
+ try {
156
+ // className is also used as dex file name
157
+ // so it should be different from each other
158
+ String suffix = DexMakerUtils .getSha1Hex (mMember .toString ());
159
+ className = className + suffix ;
160
+ String dexFileName = className + ".jar" ;
161
+ File dexFile = new File (ConfigManager .getCachePath (dexFileName ));
162
+ if (!dexFile .exists ()) {
163
+ // if file exists, reuse it and skip generating
164
+ DexLog .d ("Generating " + dexFileName );
165
+ doGenerate (className );
166
+ loader = mDexMaker .generateAndLoad (mAppClassLoader , new File (ConfigManager .getCachePath ("" )), dexFileName , false );
167
+ dexFile .setWritable (true , false );
168
+ dexFile .setReadable (true , false );
169
+ } else {
170
+ DexLog .d ("Using cache " + dexFileName );
171
+ loader = mDexMaker .loadClassDirect (mAppClassLoader , new File (ConfigManager .getCachePath ("" )), dexFileName );
172
+ }
173
+ usedCache = true ;
174
+ } catch (Throwable ignored ) {}
175
+ }
176
+ if (!usedCache ) {
168
177
// do everything in memory
178
+ DexLog .d ("Generating in memory" );
169
179
if (BuildConfig .DEBUG )
170
180
className = className + hookedClassName .replace ("." , "/" );
171
181
doGenerate (className );
0 commit comments