开发者

Proper way to use reflection on inherited methods

I've used the TouchInterceptor class in the Google Music application in my application. This class allows you to drag and drop list items into different positions in the list.

The TouchInterceptor class makes a call to a method called smoothScrollBy. This method is only available in API 8+.

I want to target my application at API 7+, so I need to use reflection to execute smoothScrollBy only if it exists.

In the constructor for TouchInterceptor, I've added the following:

    Method[] ms = this.getClass().getDeclaredMethods();
    if (ms != null) {
        for (Method m : ms) {
            if (m != null && m.toGenericString().equals("smoothScrollBy")) {
                Class[] parameters = m.getParameterTypes();
                if (parameters != null && parameters.length == 1 && parameters[0].getName().equals("int")) {
                    mSmoothScrollBy = m;
                }
            }
        }
    }

This should find the smoothScrollBy method and assign it to a new member variable of TouchInterceptor called mSmoothScrollBy (Method).

I'm debugging through on an Android 2.2 (API 8) emulator and unfortunately the method is never found. My guess is getDeclaredMethods() does not return it in the array because smoothScrollBy is a method of AbsListView, which is inherited by ListView and ultimately TouchInterceptor.

I've tried casting this to AbsListView before calling getClass().getDeclaredMethods() with no success.

How can I properly get ahold of smoothScrollBy so I can invoke it when available?

Update:

I've also tried the following to no avail:

        Method test = null;
        try {
            test = this.getClass().getMethod("smoo开发者_C百科thScrollBy", new Class[] { Integer.class });
        }
        catch (NoSuchMethodException e) {

        }


It is because it is an inherited method. getDeclaredMethods() only retrieves methods declared within your class, not the methods of its superclasses. Although I have never actually done this, you should be able to call getSuperclass() until you find the class that declares the method (AbsListView) and get the method from it.

An easier answer might be just to check the version of the API though: Programmatically obtain the Android API level of a device?


I'm not sure, but I think if you target your application to API 7, then the method won't be found, cause it won't exist. You can target API 8 and list in your manifest that you only require API level 7.


Create a method called hasMethod(Class cls, String method) or similar which recursively calls itself up the inheritance hierarchy:

public boolean hasMethod(Class cls, String method) {
    // check if cls has the method, if it does return true
    // if cls == Object.class, return false
    // else, make recursive call
    return hasMethod(cls.getSuperclass(), method);
}


Thanks for your replies. I've solved the problem by doing the following:

    try {
        mSmoothScrollBy = this.getClass().getMethod("smoothScrollBy", new Class[] { int.class, int.class });
    }
    catch (NoSuchMethodException e) {

    }

I had the parameter list of the method I was looking for incorrect.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜