解决换肤框架与高德地图的冲突
直接通过内存地址替换整个 ArtMethod ,完成了高德地图方法的替换。
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package com.mogo.module.common.hook;
|
||||
|
||||
|
||||
import android.util.Pair;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 替换管理
|
||||
* Created by donghongyu on 12/29/20 1:34 PM
|
||||
*/
|
||||
public final class HookManager {
|
||||
|
||||
private HookManager() {
|
||||
}
|
||||
|
||||
public static HookManager get() {
|
||||
return InstanceHolder.sInstance;
|
||||
}
|
||||
|
||||
private static class InstanceHolder {
|
||||
private static HookManager sInstance = new HookManager();
|
||||
}
|
||||
|
||||
private Map<Pair<String, String>, MethodHook> methodHookMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 替换方法
|
||||
*
|
||||
* @param originMethod 原始方法
|
||||
* @param hookMethod 替换方法
|
||||
*/
|
||||
public void hookMethod(Method originMethod, Method hookMethod) {
|
||||
if (originMethod == null || hookMethod == null) {
|
||||
throw new IllegalArgumentException("argument cannot be null");
|
||||
}
|
||||
|
||||
Pair<String, String> key = Pair.create(hookMethod.getDeclaringClass().getName(), hookMethod.getName());
|
||||
if (methodHookMap.containsKey(key)) {
|
||||
MethodHook methodHook = methodHookMap.get(key);
|
||||
methodHook.restore();
|
||||
}
|
||||
MethodHook methodHook = new MethodHook(originMethod, hookMethod);
|
||||
methodHookMap.put(key, methodHook);
|
||||
methodHook.hook();
|
||||
}
|
||||
|
||||
public void callOrigin(Object receiver, Object... args) {
|
||||
StackTraceElement stackTrace = Thread.currentThread().getStackTrace()[3];
|
||||
String className = stackTrace.getClassName();
|
||||
String methodName = stackTrace.getMethodName();
|
||||
MethodHook methodHook = methodHookMap.get(Pair.create(className, methodName));
|
||||
if (methodHook != null) {
|
||||
try {
|
||||
methodHook.callOrigin(receiver, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.mogo.module.common.hook;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 替换类与c++代码对应
|
||||
* Created by donghongyu on 12/29/20 1:34 PM
|
||||
*/
|
||||
public class MethodHook {
|
||||
|
||||
public static void m1() {
|
||||
}
|
||||
|
||||
public static void m2() {
|
||||
}
|
||||
|
||||
// 目标方法
|
||||
private Method srcMethod;
|
||||
// 要替换的方法
|
||||
private Method hookMethod;
|
||||
|
||||
// 备份目标替换方法ID
|
||||
private long backupMethodPtr;
|
||||
|
||||
public MethodHook(Method src, Method dest) {
|
||||
srcMethod = src;
|
||||
hookMethod = dest;
|
||||
srcMethod.setAccessible(true);
|
||||
hookMethod.setAccessible(true);
|
||||
}
|
||||
|
||||
public void hook() {
|
||||
if (backupMethodPtr == 0) {
|
||||
backupMethodPtr = hook_native(srcMethod, hookMethod);
|
||||
}
|
||||
}
|
||||
|
||||
public void restore() {
|
||||
if (backupMethodPtr != 0) {
|
||||
restore_native(srcMethod, backupMethodPtr);
|
||||
backupMethodPtr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void callOrigin(Object receiver, Object... args) throws InvocationTargetException, IllegalAccessException {
|
||||
if (backupMethodPtr != 0) {
|
||||
restore();
|
||||
srcMethod.invoke(receiver, args);
|
||||
hook();
|
||||
} else {
|
||||
srcMethod.invoke(receiver, args);
|
||||
}
|
||||
}
|
||||
|
||||
private static native long hook_native(Method src, Method dest);
|
||||
|
||||
private static native Method restore_native(Method src, long methodPtr);
|
||||
|
||||
static {
|
||||
System.loadLibrary("method-hook-lib");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user