android-studio - Android 反射获取方法 ClassNotFoundException

查看:155
本文介绍了android-studio - Android 反射获取方法 ClassNotFoundException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

我是想获取Bundle中持有的mMap集合.
bundle类中,有getMap()方法可以获取,但是被标记为hide,所以我用反射去取.

        ArrayMap<String, Object> metaMap= null;
        try {
            Class ownerClass = Class.forName(Bundle.class.getName());
            Class superclass = ownerClass.getSuperclass();
            Method[] declaredMethods = superclass.getDeclaredMethods();
//            getMapMethod.setAccessible(true);
//            metaMap= (ArrayMap<String, Object>) getMapMethod.invoke(metaData);
            Log.e("test","superclass: "+superclass.getName());
            declaredMethods.toString();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

这是我测试的代码,之前是直接调方法,然后抛异常了.于是我就打印了所有的方法:

0 = {Method@4216} "public void android.os.BaseBundle.clear()"
1 = {Method@4217} "public boolean android.os.BaseBundle.containsKey(java.lang.String)"
2 = {Method@4218} "public java.lang.Object android.os.BaseBundle.get(java.lang.String)"
3 = {Method@4219} "public boolean android.os.BaseBundle.getBoolean(java.lang.String)"
4 = {Method@4220} "public boolean android.os.BaseBundle.getBoolean(java.lang.String,boolean)"
5 = {Method@4221} "public [Z android.os.BaseBundle.getBooleanArray(java.lang.String)"
6 = {Method@4222} "byte android.os.BaseBundle.getByte(java.lang.String)"
7 = {Method@4223} "java.lang.Byte android.os.BaseBundle.getByte(java.lang.String,byte)"
8 = {Method@4224} "[B android.os.BaseBundle.getByteArray(java.lang.String)"
9 = {Method@4225} "char android.os.BaseBundle.getChar(java.lang.String)"
10 = {Method@4226} "char android.os.BaseBundle.getChar(java.lang.String,char)"
11 = {Method@4227} "[C android.os.BaseBundle.getCharArray(java.lang.String)"
12 = {Method@4228} "java.lang.CharSequence android.os.BaseBundle.getCharSequence(java.lang.String)"
13 = {Method@4229} "java.lang.CharSequence android.os.BaseBundle.getCharSequence(java.lang.String,java.lang.CharSequence)"
14 = {Method@4230} "[Ljava.lang.CharSequence; android.os.BaseBundle.getCharSequenceArray(java.lang.String)"
15 = {Method@4231} "java.util.ArrayList android.os.BaseBundle.getCharSequenceArrayList(java.lang.String)"
16 = {Method@4232} "java.lang.ClassLoader android.os.BaseBundle.getClassLoader()"
17 = {Method@4233} "public double android.os.BaseBundle.getDouble(java.lang.String)"
18 = {Method@4234} "public double android.os.BaseBundle.getDouble(java.lang.String,double)"
19 = {Method@4235} "public [D android.os.BaseBundle.getDoubleArray(java.lang.String)"
20 = {Method@4236} "float android.os.BaseBundle.getFloat(java.lang.String)"
21 = {Method@4237} "float android.os.BaseBundle.getFloat(java.lang.String,float)"
22 = {Method@4238} "[F android.os.BaseBundle.getFloatArray(java.lang.String)"
23 = {Method@4239} "public int android.os.BaseBundle.getInt(java.lang.String)"
24 = {Method@4240} "public int android.os.BaseBundle.getInt(java.lang.String,int)"
25 = {Method@4241} "public [I android.os.BaseBundle.getIntArray(java.lang.String)"
26 = {Method@4242} "java.util.ArrayList android.os.BaseBundle.getIntegerArrayList(java.lang.String)"
27 = {Method@4243} "public long android.os.BaseBundle.getLong(java.lang.String)"
28 = {Method@4244} "public long android.os.BaseBundle.getLong(java.lang.String,long)"
29 = {Method@4245} "public [J android.os.BaseBundle.getLongArray(java.lang.String)"
30 = {Method@4246} "public java.lang.String android.os.BaseBundle.getPairValue()"
31 = {Method@4247} "java.io.Serializable android.os.BaseBundle.getSerializable(java.lang.String)"
32 = {Method@4248} "short android.os.BaseBundle.getShort(java.lang.String)"
33 = {Method@4249} "short android.os.BaseBundle.getShort(java.lang.String,short)"
34 = {Method@4250} "[S android.os.BaseBundle.getShortArray(java.lang.String)"
35 = {Method@4251} "public java.lang.String android.os.BaseBundle.getString(java.lang.String)"
36 = {Method@4252} "public java.lang.String android.os.BaseBundle.getString(java.lang.String,java.lang.String)"
37 = {Method@4253} "public [Ljava.lang.String; android.os.BaseBundle.getStringArray(java.lang.String)"
38 = {Method@4254} "java.util.ArrayList android.os.BaseBundle.getStringArrayList(java.lang.String)"
39 = {Method@4255} "public boolean android.os.BaseBundle.isEmpty()"
40 = {Method@4256} "public boolean android.os.BaseBundle.isParcelled()"
41 = {Method@4257} "public java.util.Set android.os.BaseBundle.keySet()"
42 = {Method@4258} "public void android.os.BaseBundle.putAll(android.os.PersistableBundle)"
43 = {Method@4259} "void android.os.BaseBundle.putAll(android.util.ArrayMap)"
44 = {Method@4260} "public void android.os.BaseBundle.putBoolean(java.lang.String,boolean)"
45 = {Method@4261} "public void android.os.BaseBundle.putBooleanArray(java.lang.String,boolean[])"
46 = {Method@4262} "void android.os.BaseBundle.putByte(java.lang.String,byte)"
47 = {Method@4263} "void android.os.BaseBundle.putByteArray(java.lang.String,byte[])"
48 = {Method@4264} "void android.os.BaseBundle.putChar(java.lang.String,char)"
49 = {Method@4265} "void android.os.BaseBundle.putCharArray(java.lang.String,char[])"
50 = {Method@4266} "void android.os.BaseBundle.putCharSequence(java.lang.String,java.lang.CharSequence)"
51 = {Method@4267} "void android.os.BaseBundle.putCharSequenceArray(java.lang.String,java.lang.CharSequence[])"
52 = {Method@4268} "void android.os.BaseBundle.putCharSequenceArrayList(java.lang.String,java.util.ArrayList)"
53 = {Method@4269} "public void android.os.BaseBundle.putDouble(java.lang.String,double)"
54 = {Method@4270} "public void android.os.BaseBundle.putDoubleArray(java.lang.String,double[])"
55 = {Method@4271} "void android.os.BaseBundle.putFloat(java.lang.String,float)"
56 = {Method@4272} "void android.os.BaseBundle.putFloatArray(java.lang.String,float[])"
57 = {Method@4273} "public void android.os.BaseBundle.putInt(java.lang.String,int)"
58 = {Method@4274} "public void android.os.BaseBundle.putIntArray(java.lang.String,int[])"
59 = {Method@4275} "void android.os.BaseBundle.putIntegerArrayList(java.lang.String,java.util.ArrayList)"
60 = {Method@4276} "public void android.os.BaseBundle.putLong(java.lang.String,long)"
61 = {Method@4277} "public void android.os.BaseBundle.putLongArray(java.lang.String,long[])"
62 = {Method@4278} "void android.os.BaseBundle.putSerializable(java.lang.String,java.io.Serializable)"
63 = {Method@4279} "void android.os.BaseBundle.putShort(java.lang.String,short)"
64 = {Method@4280} "void android.os.BaseBundle.putShortArray(java.lang.String,short[])"
65 = {Method@4281} "public void android.os.BaseBundle.putString(java.lang.String,java.lang.String)"
66 = {Method@4282} "public void android.os.BaseBundle.putStringArray(java.lang.String,java.lang.String[])"
67 = {Method@4283} "void android.os.BaseBundle.putStringArrayList(java.lang.String,java.util.ArrayList)"
68 = {Method@4284} "void android.os.BaseBundle.readFromParcelInner(android.os.Parcel)"
69 = {Method@4285} "public void android.os.BaseBundle.remove(java.lang.String)"
70 = {Method@4286} "void android.os.BaseBundle.setClassLoader(java.lang.ClassLoader)"
71 = {Method@4287} "public int android.os.BaseBundle.size()"
72 = {Method@4288} "void android.os.BaseBundle.typeWarning(java.lang.String,java.lang.Object,java.lang.String,java.lang.ClassCastException)"
73 = {Method@4289} "void android.os.BaseBundle.typeWarning(java.lang.String,java.lang.Object,java.lang.String,java.lang.Object,java.lang.ClassCastException)"
74 = {Method@4290} "synchronized void android.os.BaseBundle.unparcel()"
75 = {Method@4291} "void android.os.BaseBundle.writeToParcelInner(android.os.Parcel,int)"
76 = {Method@4292} "private void android.os.BaseBundle.readFromParcelInner(android.os.Parcel,int)"

我在源码中看到的方法如下:(只复制了方法名.)

BaseBundle
BaseBundle
BaseBundle
BaseBundle
BaseBundle
BaseBundle
BaseBundle
clear
containsKey
get
getBoolean
getBoolean
getBooleanArray
getByte
getByte
getByteArray
getChar
getChar
getCharArray
getCharSequence
getCharSequence
getCharSequenceArray
getCharSequenceArrayList
getClassLoader
getDouble
getDouble
getDoubleArray
getFloat
getFloat
getFloatArray
getInt
getInt
getIntArray
getIntegerArrayList
getLong
getLong
getLongArray
getMap
getPairValue
getSerializable
getShort
getShort
getShortArray
getString
getString
getStringArray
getStringArrayList
isEmpty
isEmptyParcel
isParcelled
keySet
putAll
putAll
putBoolean
putBooleanArray
putByte
putByteArray
putChar
putCharArray
putCharSequence
putCharSequenceArray
putCharSequenceArrayList
putDouble
putDoubleArray
putFloat
putFloatArray
putInt
putIntArray
putIntegerArrayList
putLong
putLongArray
putSerializable
putShort
putShortArray
putString
putStringArray
putStringArrayList
readFromParcelInner
readFromParcelInner
remove
setClassLoader
setShouldDefuse
size
typeWarning
typeWarning
unparcel
writeToParcelInner

其中,isParcelled(),getPairValue()也是被标记为hide,但是却能获取到.想问问是为什么?

我猜测是sdk版本原因,我的手机是sdk = 23,我编译的版本为25,我猜测那几个没获取到的方法是23之后添加的,不知有没有什么可以查看sdk版本差异测方法,或者是其他的原因.

解决方案

我对比了下 Api23和Api25两个的Bundle源码,没有关于getMap的明显信息,
然后又对比了下Api16和Api25两个的Bundle源码,发现端倪,如下图黄色块标注:

我们可以看到Api25上,Bundle extends BaseBundle,而Api16却没有,而且两边采用的数据结构也发生了变化。

我们看下Api25上的BaseBundle,确实有getMap :

/** @hide */
ArrayMap<String, Object> getMap() {
    unparcel();
    return mMap;
}

然后我们在看下在Api23的BaseBundle里面搜getMap,结果如下:

很明显,在Api23上,无论是Bundle,还是它的父类BaseBundle,都是不存在getMap方法的,所以反射也调不到。

这篇关于android-studio - Android 反射获取方法 ClassNotFoundException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆