2013-11-02 54 views
5

我想弄清楚的反思与该Android类: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作为接收器?

回答

10

您正在通过class#invoke()而不是LockPatternUtils的实例。

您可以使用#newInstance()创建一个实例。

+0

你能对你的解答为这样'对象clazz中= c.newInstance()扩展;'然后传递'Object对象= method.invoke(clazz所)clazz中;'只会工作,如果被引用类的构造函数是空的。在类的构造函数被定义为'public LockPatternUtils(Context context){..}'的情况下,你做了什么? – ChuongPham

+0

我会通过向'newInstance'方法展示doco来标记你的答案是正确的。谢了哥们。 – ChuongPham

+0

@ChuongPham:当然,有一些限制,但它们记录在API链接到的API中。 – Keppil

1

没关系,我已经知道了。我已根据此tutorial修改了以下代码。

如果有人有兴趣的解决方案,那就是:

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年后),解决方案将需要修改。

注:以上是我了解Reflection的用法的练习。但是,在使用Android制作应用程序时,应该谨慎使用Reflection并在绝对需要时使用。

+0

我不得不稍微改变代码来得到它我的Andorid 5.1.1设备上运行,并得到正确的构造用过的。 只好改变if(constructor.getGenericParameterTypes()。length == 0) – FunkSoulBrother