6

我试图用这个 Android 类找出反射:

Class<?> c = Class.forName("com.android.internal.widget.LockPatternUtils");
Method method = c.getDeclaredMethod("getKeyguardStoredPasswordQuality");
method.setAccessible(true);
Object object = method.invoke(c); // Error with this line
result = object.toString());

该方法getKeyguardStoredPasswordQuality被声明为(无参数):

public int getKeyguardStoredPasswordQuality() {
    // codes here
}

我得到的错误是:

Exception: java.lang.IllegalArgumentException: expected receiver of type com.android.internal.widget.LockPatternUtils, but got java.lang.Class<com.android.internal.widget.LockPatternUtils>

我如何声明com.android.internal.widget.LockPatternUtils为接收方?

4

2 回答 2

14

您正在传递classto#invoke()而不是LockPatternUtils.

您可以使用#newInstance().

于 2013-11-02T10:21:22.873 回答
1

没关系,我已经想通了。我已经根据本教程调整了以下代码。

如果有人对解决方案感兴趣,这里是:

Class<?> c = Class.forName("com.android.internal.widget.LockPatternUtils");
Constructor<?>[] constructors = c.getDeclaredConstructors();
Constructor<?> constructor = null;
for (int i = 0; i < constructors.length; i++) {
   constructor = constructors[i];
   if (constructor.getGenericParameterTypes().length == 0)
      break;
}
constructor.setAccessible(true);
Object clazz = constructor.newInstance(context, true);
Method method = clazz.getClass().getDeclaredMethod("getKeyguardStoredPasswordQuality");
Object object = method.invoke(clazz);
result = object.toString();

上述方案要求LockPatternUtils.java类的公共构造函数定义为:

public LockPatternUtils(Context context) {...}

如果将来(2013 年后)构造函数发生变化,则需要修改解决方案。

注意:以上是我理解反射用法的练习。但是,在 Android 生产应用程序中使用反射应该谨慎使用,并且在绝对需要时使用。

于 2013-11-02T13:11:16.867 回答