Skip to content

Commit a1c8574

Browse files
author
RLib
committed
Improve performance for Xposed-Bridge
1 parent dab3cca commit a1c8574

File tree

6 files changed

+19
-30
lines changed

6 files changed

+19
-30
lines changed

build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22
buildscript {
33
repositories {
44
jcenter()
5+
google()
56
}
67
dependencies {
7-
classpath 'com.android.tools.build:gradle:3.0.0'
8+
classpath 'com.android.tools.build:gradle:3.0.1'
89
}
910
}
1011

1112
allprojects {
1213
repositories {
1314
jcenter()
15+
google()
1416
}
1517
}

lib/src/main/java/andhook/lib/xposed/XC_MethodHook.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public Object getResult() {
110110
* <p>
111111
* <p>If called from {@link #beforeHookedMethod}, it prevents the call to the original method.
112112
*/
113-
public void setResult(Object result) {
113+
public void setResult(final Object result) {
114114
this.result = result;
115115
this.throwable = null;
116116
this.returnEarly = true;
@@ -135,7 +135,7 @@ public boolean hasThrowable() {
135135
* <p>
136136
* <p>If called from {@link #beforeHookedMethod}, it prevents the call to the original method.
137137
*/
138-
public void setThrowable(Throwable throwable) {
138+
public void setThrowable(final Throwable throwable) {
139139
this.throwable = throwable;
140140
this.result = null;
141141
this.returnEarly = true;

lib/src/main/java/andhook/lib/xposed/XposedBridge.java

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010
import java.lang.reflect.Method;
1111
import java.lang.reflect.Modifier;
1212
import java.util.Arrays;
13-
import java.util.HashMap;
1413
import java.util.HashSet;
14+
import java.util.concurrent.ConcurrentHashMap;
1515

1616
/**
1717
* This class contains most of Xposed's central logic, such as initialization and callbacks used by
1818
* the native side. It also includes methods to add new hooks.
19+
* <p>
20+
* Latest Update 2018/01/20
1921
*/
2022
@SuppressWarnings("WeakerAccess")
2123
public final class XposedBridge {
@@ -33,7 +35,7 @@ public final class XposedBridge {
3335
private static final Object[] EMPTY_ARRAY = new Object[0];
3436

3537
// built-in handlers
36-
private static final HashMap<Member, AdditionalHookInfo> sHookedMethodInfos = new HashMap<>();
38+
private static final ConcurrentHashMap<Member, AdditionalHookInfo> sHookedMethodInfos = new ConcurrentHashMap<>();
3739

3840
/**
3941
* Writes a message to the logcat error log.
@@ -70,30 +72,28 @@ public static void log(final Throwable t) {
7072
public static XC_MethodHook.Unhook hookMethod(final Member hookMethod, final XC_MethodHook callback) {
7173
if (!(hookMethod instanceof Method) && !(hookMethod instanceof Constructor<?>)) {
7274
throw new IllegalArgumentException("Only methods and constructors can be hooked: " + hookMethod.toString());
73-
} else if (hookMethod.getDeclaringClass().isInterface()) {
74-
throw new IllegalArgumentException("Cannot hook interfaces: " + hookMethod.toString());
7575
} else if (Modifier.isAbstract(hookMethod.getModifiers())) {
7676
throw new IllegalArgumentException("Cannot hook abstract methods: " + hookMethod.toString());
7777
}
7878

79-
AdditionalHookInfo additionalInfo;
80-
synchronized (sHookedMethodInfos) {
81-
additionalInfo = sHookedMethodInfos.get(hookMethod);
82-
}
83-
79+
AdditionalHookInfo additionalInfo = sHookedMethodInfos.get(hookMethod);
8480
if (additionalInfo == null) {
8581
if (Modifier.isStatic(hookMethod.getModifiers()))
8682
AndHook.ensureClassInitialized(hookMethod.getDeclaringClass());
8783
additionalInfo = new AdditionalHookInfo(hookMethod, AndHook.backup(hookMethod));
8884
if (additionalInfo.slot == -1)
8985
throw new RuntimeException("Failed to backup methods: " + hookMethod.toString());
9086

91-
sHookedMethodInfos.put(hookMethod, additionalInfo);
9287
additionalInfo.callbacks.add(callback);
9388
if (!AndHook.hook(hookMethod, additionalInfo, additionalInfo.slot))
9489
throw new RuntimeException("Failed to hook methods: " + hookMethod.toString());
9590

91+
sHookedMethodInfos.put(hookMethod, additionalInfo);
9692
} else {
93+
// sanity check
94+
if (!additionalInfo.method.getDeclaringClass().getClassLoader().equals(hookMethod.getDeclaringClass().getClassLoader())) {
95+
throw new RuntimeException("Unexpected same methods within difference CL: " + hookMethod.toString());
96+
}
9797
additionalInfo.callbacks.add(callback);
9898
}
9999

@@ -111,10 +111,7 @@ public static XC_MethodHook.Unhook hookMethod(final Member hookMethod, final XC_
111111
@SuppressWarnings("all")
112112
@Deprecated
113113
public static void unhookMethod(final Member hookMethod, final XC_MethodHook callback) {
114-
AdditionalHookInfo additionalInfo;
115-
synchronized (sHookedMethodInfos) {
116-
additionalInfo = sHookedMethodInfos.get(hookMethod);
117-
}
114+
final AdditionalHookInfo additionalInfo = sHookedMethodInfos.get(hookMethod);
118115
if (additionalInfo != null) {
119116
additionalInfo.callbacks.remove(callback);
120117
}
@@ -126,9 +123,7 @@ public static void unhookMethod(final Member hookMethod, final XC_MethodHook cal
126123
* AndHook extension function.
127124
*/
128125
public static boolean unhookMethod(final int slot, final Member hookMethod) {
129-
synchronized (sHookedMethodInfos) {
130-
sHookedMethodInfos.remove(hookMethod);
131-
}
126+
sHookedMethodInfos.remove(hookMethod);
132127
return AndHook.restore(slot, hookMethod);
133128
}
134129

@@ -192,6 +187,7 @@ public static HashSet<XC_MethodHook.Unhook> hookAllConstructors(final Class<?> h
192187
/**
193188
* This method is called as a replacement for hooked methods.
194189
*/
190+
@SuppressWarnings("unused")
195191
private static Object handleHookedMethod(final Object additionalInfoObj,
196192
final Object thisObject, final Object[] args) throws Throwable {
197193
final AdditionalHookInfo additionalInfo = (AdditionalHookInfo) additionalInfoObj;
@@ -275,7 +271,7 @@ private static Object handleHookedMethod(final Object additionalInfoObj,
275271
* if the original method should be skipped.
276272
*/
277273
public static Object invokeOriginalMethod(final int slot, final Object thisObject,
278-
final Object[] args) throws Throwable {
274+
final Object[] args) {
279275
return AndHook.invokeMethod(slot, thisObject, args);
280276
}
281277

@@ -339,14 +335,5 @@ private AdditionalHookInfo(final Member method, final int slot) {
339335
this.method = method;
340336
this.slot = slot;
341337
}
342-
343-
/**
344-
* AndHook method bridge.
345-
*/
346-
@SuppressWarnings("unused")
347-
private static Object bridge(final Object thiz, final Object receiver, final Object[] args)
348-
throws Throwable {
349-
return XposedBridge.handleHookedMethod(thiz, receiver, args);
350-
}
351338
}
352339
}
9.5 KB
Binary file not shown.
Binary file not shown.
9.47 KB
Binary file not shown.

0 commit comments

Comments
 (0)