Maison  >  Questions et réponses  >  le corps du texte

android-studio - Méthode d'acquisition de réflexion Android ClassNotFoundException

Je veux obtenir Bundle中持有的mMap集合.
bundle类中,有getMap()方法可以获取,但是被标记为hide, alors j'utilise la réflexion pour l'obtenir.

        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();
        }

C'est le code que j'ai testé. Avant, j'appelais la méthode directement, puis une exception était levée. J'ai donc imprimé toutes les méthodes :

.
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)"

La méthode que j'ai vue dans le code source est la suivante : (Seul le nom de la méthode est copié.)

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

Parmi eux, isParcelled(),getPairValue()也是被标记为hide, mais cela peut être obtenu, je veux demander pourquoi ?

.

Je suppose que c'est à cause de la version du SDK. Mon téléphone portable est sdk = 23,我编译的版本为25 Je suppose que les méthodes qui ne sont pas obtenues ont été ajoutées après 23. Je me demande s'il existe une méthode pour vérifier la différence de version du SDK, ou s'il y a d'autres raisons.

PHP中文网PHP中文网2713 Il y a quelques jours1146

répondre à tous(2)je répondrai

  • 巴扎黑

    巴扎黑2017-05-16 13:26:23

    J'ai comparé le code source du Bundle d'Api23 et d'Api25, et il n'y avait aucune information évidente sur getMap.
    Ensuite, j'ai comparé le code source du Bundle d'Api16 et d'Api25, et j'ai trouvé des indices, comme le montre le bloc jaune dans l'image ci-dessous :

    On voit que sur Api25, Bundle étend BaseBundle, mais pas sur Api16, et les structures de données utilisées des deux côtés ont également changé.

    Jetons un œil au BaseBundle sur Api25, et il y a bien getMap :

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

    Ensuite, regardons la recherche de getMap dans le BaseBundle d'Api23. Les résultats sont les suivants :

    Évidemment, Sur Api23, il n'y a pas de méthode getMap dans Bundle ou dans sa classe parent BaseBundle, donc la réflexion ne peut pas être. ajusté non plus.

    répondre
    0
  • 为情所困

    为情所困2017-05-16 13:26:23

    @hide appartient à une balise javadoc. Lorsque le code source du Bundle est compilé dans un package jar, les méthodes marquées avec @hide seront exclues. Le package jar généré est destiné aux développeurs, nous ne pouvons donc pas le transmettre directement dans l'EDI. La référence à l'objet bundle appelle directement la méthode hide de la classe bundle. Ce n'est pas différent de la version compilée du SDK.
    Après vous être familiarisé avec Android dans son ensemble, vous pouvez essayer de compiler le code source d'Android pour générer votre propre package android.jar. Par exemple, il existe de nombreux développements de caméras ici, et de nombreuses méthodes de caméra ont été cachées par nous. Je ne veux pas appeler la méthode hide par réflexion à chaque fois, nous avons donc compilé nous-mêmes un ensemble complet de packages android.jar. Les méthodes cachées dans la caméra peuvent être appelées directement dans l'EDI.

    répondre
    0
  • Annulerrépondre