0

我正在尝试使用 javassist 来检查 Android 类的内容。我这样做的目的无关紧要,请向我解释为什么会发生以下情况:

当我用反射检查类 com.android.Intent 时,我得到了一个巨大的类列表。当我使用 javassist 时,我得到的很少。为什么会存在这种差异?不应该有相同数量的方法吗?这是我的 javassist 代码:

final ClassPool pool = ClassPool.getDefault(getApplicationContext());
final CtClass cc = pool.get("android.content.Intent");
CtMethod[] mts = cc.getDeclaredMethods();

for (int i = 0; i < mts.length; i++) {
    System.out.println("JAVASSIST: " + mts[i].toString());
}

这是输出:

12-03 14:42:23.819: I/System.out(2308): JAVASSIST: javassist.CtMethod@33a3ff1e[protected clone ()Ljava/lang/Object;]
12-03 14:42:23.819: I/System.out(2308): JAVASSIST: javassist.CtMethod@87a44f24[public equals (Ljava/lang/Object;)Z]
12-03 14:42:23.819: I/System.out(2308): JAVASSIST: javassist.CtMethod@919e519f[protected finalize ()V]
12-03 14:42:23.828: I/System.out(2308): JAVASSIST: javassist.CtMethod@70ae6c43[public final native getClass ()Ljava/lang/Class;]
12-03 14:42:23.828: I/System.out(2308): JAVASSIST: javassist.CtMethod@c13165c[public native hashCode ()I]
12-03 14:42:23.838: I/System.out(2308): JAVASSIST: javassist.CtMethod@5e7eee0a[public final native notify ()V]
12-03 14:42:23.838: I/System.out(2308): JAVASSIST: javassist.CtMethod@96773899[public final native notifyAll ()V]
12-03 14:42:23.838: I/System.out(2308): JAVASSIST: javassist.CtMethod@69cb6c6d[public toString ()Ljava/lang/String;]
12-03 14:42:23.838: I/System.out(2308): JAVASSIST: javassist.CtMethod@d0990d36[public final wait ()V]
12-03 14:42:23.838: I/System.out(2308): JAVASSIST: javassist.CtMethod@42889db2[public final wait (J)V]
12-03 14:42:23.849: I/System.out(2308): JAVASSIST: javassist.CtMethod@e8b1c97[public final native wait (JI)V]
12-03 14:42:23.849: I/System.out(2308): JAVASSIST: javassist.CtMethod@7e58240d[private native internalClone (Ljava/lang/Cloneable;)Ljava/lang/Object;]

然而,很明显它缺少许多附加到这个类的 50 多个函数。这是我使用反射的代码:

Class<?> c = Class.forName("android.content.Intent");
Method[] allMethods = c.getDeclaredMethods();
for (int i = 0; i < allMethods.length; i++) {
    System.out.println("REFLECTION: " + allMethods[i].toString());
}

这是输出:

12-03 14:42:23.869: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.addCategory(java.lang.String)
12-03 14:42:23.869: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.addFlags(int)
12-03 14:42:23.878: I/System.out(2308): REFLECTION: public java.lang.Object android.content.Intent.clone()
12-03 14:42:23.878: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.cloneFilter()
12-03 14:42:23.878: I/System.out(2308): REFLECTION: public int android.content.Intent.describeContents()
12-03 14:42:23.889: I/System.out(2308): REFLECTION: public int android.content.Intent.fillIn(android.content.Intent,int)
12-03 14:42:23.889: I/System.out(2308): REFLECTION: public boolean android.content.Intent.filterEquals(android.content.Intent)
12-03 14:42:23.889: I/System.out(2308): REFLECTION: public int android.content.Intent.filterHashCode()
12-03 14:42:23.889: I/System.out(2308): REFLECTION: public java.lang.String android.content.Intent.getAction()
12-03 14:42:23.899: I/System.out(2308): REFLECTION: public [Z android.content.Intent.getBooleanArrayExtra(java.lang.String)
12-03 14:42:23.899: I/System.out(2308): REFLECTION: public boolean android.content.Intent.getBooleanExtra(java.lang.String,boolean)
12-03 14:42:23.899: I/System.out(2308): REFLECTION: public android.os.Bundle android.content.Intent.getBundleExtra(java.lang.String)
12-03 14:42:23.899: I/System.out(2308): REFLECTION: public [B android.content.Intent.getByteArrayExtra(java.lang.String)
12-03 14:42:23.899: I/System.out(2308): REFLECTION: public byte android.content.Intent.getByteExtra(java.lang.String,byte)
12-03 14:42:23.909: I/System.out(2308): REFLECTION: public java.util.Set android.content.Intent.getCategories()
12-03 14:42:23.909: I/System.out(2308): REFLECTION: public [C android.content.Intent.getCharArrayExtra(java.lang.String)
12-03 14:42:23.909: I/System.out(2308): REFLECTION: public char android.content.Intent.getCharExtra(java.lang.String,char)
12-03 14:42:23.909: I/System.out(2308): REFLECTION: public [Ljava.lang.CharSequence; android.content.Intent.getCharSequenceArrayExtra(java.lang.String)
12-03 14:42:23.909: I/System.out(2308): REFLECTION: public java.util.ArrayList android.content.Intent.getCharSequenceArrayListExtra(java.lang.String)
12-03 14:42:23.918: I/System.out(2308): REFLECTION: public java.lang.CharSequence android.content.Intent.getCharSequenceExtra(java.lang.String)
12-03 14:42:23.918: I/System.out(2308): REFLECTION: public android.content.ComponentName android.content.Intent.getComponent()
12-03 14:42:23.918: I/System.out(2308): REFLECTION: public android.net.Uri android.content.Intent.getData()
12-03 14:42:23.928: I/System.out(2308): REFLECTION: public java.lang.String android.content.Intent.getDataString()
12-03 14:42:23.928: I/System.out(2308): REFLECTION: public [D android.content.Intent.getDoubleArrayExtra(java.lang.String)
12-03 14:42:23.928: I/System.out(2308): REFLECTION: public double android.content.Intent.getDoubleExtra(java.lang.String,double)
12-03 14:42:23.939: I/System.out(2308): REFLECTION: public java.lang.Object android.content.Intent.getExtra(java.lang.String)
12-03 14:42:23.939: I/System.out(2308): REFLECTION: public java.lang.Object android.content.Intent.getExtra(java.lang.String,java.lang.Object)
12-03 14:42:23.949: I/System.out(2308): REFLECTION: public android.os.Bundle android.content.Intent.getExtras()
12-03 14:42:23.949: I/System.out(2308): REFLECTION: public int android.content.Intent.getFlags()
12-03 14:42:23.949: I/System.out(2308): REFLECTION: public [F android.content.Intent.getFloatArrayExtra(java.lang.String)
12-03 14:42:23.959: I/System.out(2308): REFLECTION: public float android.content.Intent.getFloatExtra(java.lang.String,float)
12-03 14:42:23.959: I/System.out(2308): REFLECTION: public android.os.IBinder android.content.Intent.getIBinderExtra(java.lang.String)
12-03 14:42:23.959: I/System.out(2308): REFLECTION: public [I android.content.Intent.getIntArrayExtra(java.lang.String)
12-03 14:42:23.959: I/System.out(2308): REFLECTION: public int android.content.Intent.getIntExtra(java.lang.String,int)
12-03 14:42:23.959: I/System.out(2308): REFLECTION: public java.util.ArrayList android.content.Intent.getIntegerArrayListExtra(java.lang.String)
12-03 14:42:23.959: I/System.out(2308): REFLECTION: public [J android.content.Intent.getLongArrayExtra(java.lang.String)
12-03 14:42:23.959: I/System.out(2308): REFLECTION: public long android.content.Intent.getLongExtra(java.lang.String,long)
12-03 14:42:23.968: I/System.out(2308): REFLECTION: public java.lang.String android.content.Intent.getPackage()
12-03 14:42:23.968: I/System.out(2308): REFLECTION: public [Landroid.os.Parcelable; android.content.Intent.getParcelableArrayExtra(java.lang.String)
12-03 14:42:23.968: I/System.out(2308): REFLECTION: public java.util.ArrayList android.content.Intent.getParcelableArrayListExtra(java.lang.String)
12-03 14:42:23.968: I/System.out(2308): REFLECTION: public android.os.Parcelable android.content.Intent.getParcelableExtra(java.lang.String)
12-03 14:42:23.968: I/System.out(2308): REFLECTION: public java.lang.String android.content.Intent.getScheme()
12-03 14:42:23.968: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.getSelector()
12-03 14:42:23.968: I/System.out(2308): REFLECTION: public java.io.Serializable android.content.Intent.getSerializableExtra(java.lang.String)
12-03 14:42:23.968: I/System.out(2308): REFLECTION: public [S android.content.Intent.getShortArrayExtra(java.lang.String)
12-03 14:42:23.978: I/System.out(2308): REFLECTION: public short android.content.Intent.getShortExtra(java.lang.String,short)
12-03 14:42:23.978: I/System.out(2308): REFLECTION: public android.graphics.Rect android.content.Intent.getSourceBounds()
12-03 14:42:23.978: I/System.out(2308): REFLECTION: public [Ljava.lang.String; android.content.Intent.getStringArrayExtra(java.lang.String)
12-03 14:42:23.978: I/System.out(2308): REFLECTION: public java.util.ArrayList android.content.Intent.getStringArrayListExtra(java.lang.String)
12-03 14:42:23.978: I/System.out(2308): REFLECTION: public java.lang.String android.content.Intent.getStringExtra(java.lang.String)
12-03 14:42:23.978: I/System.out(2308): REFLECTION: public java.lang.String android.content.Intent.getType()
12-03 14:42:23.989: I/System.out(2308): REFLECTION: public boolean android.content.Intent.hasCategory(java.lang.String)
12-03 14:42:23.989: I/System.out(2308): REFLECTION: public boolean android.content.Intent.hasExtra(java.lang.String)
12-03 14:42:23.989: I/System.out(2308): REFLECTION: public boolean android.content.Intent.hasFileDescriptors()
12-03 14:42:23.989: I/System.out(2308): REFLECTION: public boolean android.content.Intent.isExcludingStopped()
12-03 14:42:23.989: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putCharSequenceArrayListExtra(java.lang.String,java.util.ArrayList)
12-03 14:42:23.989: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,byte)
12-03 14:42:23.989: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,char)
12-03 14:42:23.999: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,double)
12-03 14:42:23.999: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,float)
12-03 14:42:23.999: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,int)
12-03 14:42:23.999: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,long)
12-03 14:42:23.999: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,android.os.Bundle)
12-03 14:42:24.008: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,android.os.IBinder)
12-03 14:42:24.008: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,android.os.Parcelable)
12-03 14:42:24.008: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,java.io.Serializable)
12-03 14:42:24.019: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,java.lang.CharSequence)
12-03 14:42:24.019: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,java.lang.String)
12-03 14:42:24.028: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,short)
12-03 14:42:24.028: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,boolean)
12-03 14:42:24.028: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,[B)
12-03 14:42:24.028: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,[C)
12-03 14:42:24.028: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,[D)
12-03 14:42:24.039: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,[F)
12-03 14:42:24.039: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,[I)
12-03 14:42:24.039: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,[J)
12-03 14:42:24.039: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,[Landroid.os.Parcelable;)
12-03 14:42:24.039: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,[Ljava.lang.CharSequence;)
12-03 14:42:24.039: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,[Ljava.lang.String;)
12-03 14:42:24.048: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,[S)
12-03 14:42:24.048: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtra(java.lang.String,[Z)
12-03 14:42:24.048: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtras(android.content.Intent)
12-03 14:42:24.048: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putExtras(android.os.Bundle)
12-03 14:42:24.048: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putIntegerArrayListExtra(java.lang.String,java.util.ArrayList)
12-03 14:42:24.048: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putParcelableArrayListExtra(java.lang.String,java.util.ArrayList)
12-03 14:42:24.048: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.putStringArrayListExtra(java.lang.String,java.util.ArrayList)
12-03 14:42:24.058: I/System.out(2308): REFLECTION: public void android.content.Intent.readFromParcel(android.os.Parcel)
12-03 14:42:24.058: I/System.out(2308): REFLECTION: public void android.content.Intent.removeCategory(java.lang.String)
12-03 14:42:24.058: I/System.out(2308): REFLECTION: public void android.content.Intent.removeExtra(java.lang.String)
12-03 14:42:24.058: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.replaceExtras(android.content.Intent)
12-03 14:42:24.058: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.replaceExtras(android.os.Bundle)
12-03 14:42:24.058: I/System.out(2308): REFLECTION: public android.content.ComponentName android.content.Intent.resolveActivity(android.content.pm.PackageManager)
12-03 14:42:24.058: I/System.out(2308): REFLECTION: public android.content.pm.ActivityInfo android.content.Intent.resolveActivityInfo(android.content.pm.PackageManager,int)
12-03 14:42:24.068: I/System.out(2308): REFLECTION: public java.lang.String android.content.Intent.resolveType(android.content.ContentResolver)
12-03 14:42:24.068: I/System.out(2308): REFLECTION: public java.lang.String android.content.Intent.resolveType(android.content.Context)
12-03 14:42:24.068: I/System.out(2308): REFLECTION: public java.lang.String android.content.Intent.resolveTypeIfNeeded(android.content.ContentResolver)
12-03 14:42:24.068: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.setAction(java.lang.String)
12-03 14:42:24.079: I/System.out(2308): REFLECTION: public void android.content.Intent.setAllowFds(boolean)
12-03 14:42:24.079: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.setClass(android.content.Context,java.lang.Class)
12-03 14:42:24.079: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.setClassName(android.content.Context,java.lang.String)
12-03 14:42:24.079: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.setClassName(java.lang.String,java.lang.String)
12-03 14:42:24.079: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.setComponent(android.content.ComponentName)
12-03 14:42:24.079: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.setData(android.net.Uri)
12-03 14:42:24.079: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.setDataAndType(android.net.Uri,java.lang.String)
12-03 14:42:24.079: I/System.out(2308): REFLECTION: public void android.content.Intent.setExtrasClassLoader(java.lang.ClassLoader)
12-03 14:42:24.089: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.setFlags(int)
12-03 14:42:24.089: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.setPackage(java.lang.String)
12-03 14:42:24.089: I/System.out(2308): REFLECTION: public void android.content.Intent.setSelector(android.content.Intent)
12-03 14:42:24.089: I/System.out(2308): REFLECTION: public void android.content.Intent.setSourceBounds(android.graphics.Rect)
12-03 14:42:24.098: I/System.out(2308): REFLECTION: public android.content.Intent android.content.Intent.setType(java.lang.String)
12-03 14:42:24.108: I/System.out(2308): REFLECTION: public java.lang.String android.content.Intent.toInsecureString()
12-03 14:42:24.108: I/System.out(2308): REFLECTION: public java.lang.String android.content.Intent.toShortString(boolean,boolean,boolean)
12-03 14:42:24.108: I/System.out(2308): REFLECTION: public void android.content.Intent.toShortString(java.lang.StringBuilder,boolean,boolean,boolean)
12-03 14:42:24.108: I/System.out(2308): REFLECTION: public java.lang.String android.content.Intent.toString()
12-03 14:42:24.108: I/System.out(2308): REFLECTION: public java.lang.String android.content.Intent.toURI()
12-03 14:42:24.108: I/System.out(2308): REFLECTION: public java.lang.String android.content.Intent.toUri(int)
12-03 14:42:24.118: I/System.out(2308): REFLECTION: public void android.content.Intent.writeToParcel(android.os.Parcel,int)
12-03 14:42:24.118: I/System.out(2308): REFLECTION: public static android.content.Intent android.content.Intent.createChooser(android.content.Intent,java.lang.CharSequence)
12-03 14:42:24.118: I/System.out(2308): REFLECTION: public static android.content.Intent android.content.Intent.getIntent(java.lang.String) throws java.net.URISyntaxException
12-03 14:42:24.118: I/System.out(2308): REFLECTION: public static android.content.Intent android.content.Intent.getIntentOld(java.lang.String) throws java.net.URISyntaxException
12-03 14:42:24.118: I/System.out(2308): REFLECTION: public static android.content.Intent android.content.Intent.makeMainActivity(android.content.ComponentName)
12-03 14:42:24.118: I/System.out(2308): REFLECTION: public static android.content.Intent android.content.Intent.makeMainSelectorActivity(java.lang.String,java.lang.String)
12-03 14:42:24.118: I/System.out(2308): REFLECTION: public static android.content.Intent android.content.Intent.makeRestartActivityTask(android.content.ComponentName)
12-03 14:42:24.118: I/System.out(2308): REFLECTION: public static android.content.Intent android.content.Intent.parseIntent(android.content.res.Resources,org.xmlpull.v1.XmlPullParser,android.util.AttributeSet) throws org.xmlpull.v1.XmlPullParserException,java.io.IOException
12-03 14:42:24.118: I/System.out(2308): REFLECTION: public static android.content.Intent android.content.Intent.parseUri(java.lang.String,int) throws java.net.URISyntaxException
12-03 14:42:24.118: I/System.out(2308): REFLECTION: private void android.content.Intent.toUriInner(java.lang.StringBuilder,java.lang.String,int)

为什么 javassist 缺少这么多方法?我是否以某种方式引用了错误的 ClassPool?有任何想法吗?

4

1 回答 1

2

我对 android 堆栈并不完全熟悉,尽管我知道它可以与一个名为Dalvik VM的修改后的 JVM 一起使用。Dalvik VM 类格式完全不同,因为它是基于寄存器的架构,与通常的基于堆栈的架构相反。

我认为问题很可能是 javassist 无法完全/正确地解析类格式,只给你一些方法。

更新

经过几次搜索后,我在 SO 中找到了另一个帖子,这证实了我的怀疑。似乎 javassist 不适用于 android。虽然,似乎 ASM 确实如此。但是使用 ASM,您将在较低的抽象级别上工作。

引用用户 alokoko:

  • 可以使用 Javassist 修改 java 字节码,但它不适用于 Android 等平台。
  • 可以使用 ASM,但这涉及处理 Java 程序集(这里有一个示例:http: //community.jboss.org/thread/150002)。
于 2012-12-05T12:00:05.200 回答