一.摘要
最近在q上遇到一个问题,有同事反应为什么我反射的方法在q上找不到对应的方法了,只获得了一些class.java的方法,这是q上在art中新加的hiddenapi相关的策略做了限制导致的,那么我们来看看是怎么限制的吧
二.代码分析
1.测试代码:
void test() {
List list = new ArrayList();
Class mclass = null;
try {
mclass = Class.forName("android.app.Utils");
Log.d(TAG, mclass.getName());
// android.app.SmtPCUtils
Method[] methods = mclass.getMethods();
for (Method s : methods) {
Log.d(TAG, s.getName());
list.add(s.getName());
}
Log.d(TAG, list.toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
2.系统源码:
2.1 getMethods
public Method[] getMethods() throws SecurityException {
List<Method> methods = new ArrayList<Method>();
// 获取public方法
getPublicMethodsInternal(methods);
/*
* Remove duplicate methods defined by superclasses and
* interfaces, preferring to keep methods declared by derived
* types.
*/
CollectionUtils.removeDuplicates(methods, Method.ORDER_BY_SIGNATURE);
return methods.toArray(new Method[methods.size()]);
}
private void getPublicMethodsInternal(List<Method> result) {
// 获取该类中宣告可以调用的方法
Collections.addAll(result, getDeclaredMethodsUnchecked(true));
if (!isInterface()) {
// Search superclasses, for interfaces don't search java.lang.Object.
for (Class<?> c = superClass; c != null; c = c.superClass) {
// 获取该类的父类中可以调用的方法
Collections.addAll(result, c.getDeclaredMethodsUnchecked(true));
}
}
// Search iftable which has a flattened and uniqued list of interfaces.
Object[] iftable = ifTable;
if (iftable != null) {
for (int i = 0; i < iftable.length; i += 2) {
Class<?> ifc = (Class<?>) iftable[i];
// 获取接口方法
Collections.addAll(result, ifc.getDeclaredMethodsUnchecked(true));
}
}
}
这里我们会去获取android.app.SmtPCUtils类的所有方法:打个断点:
我们从断点中确实可以看得,我们没有获得android.app.SmtPCUtils类的方法,那我们直接看看getDeclaredMethodsUnchecked方法吧:
2.2 Class_getDeclaredMethodsUnchecked
http://aosp.opersys.com/xref/android-10.0.0_r41/xref/art/runtime/native/java_lang_Class.cc#575
static jobjectArray Class_getDeclaredMethodsUnchecked(JNIEnv* env, jobject javaThis,
jboolean publicOnly) {
ScopedFastNativeObjectAccess