1. 程式人生 > >Java筆記:[反射篇] 利用反射,獲取類中的私有內部類物件,並呼叫該物件的方法

Java筆記:[反射篇] 利用反射,獲取類中的私有內部類物件,並呼叫該物件的方法

public void smoothScrollBy(int dx, int dy, int duration) { try { Class<?> c = null; try { c = Class.forName("android.support.v7.widget.RecyclerView");//獲得Class物件 } catch (ClassNotFoundException e) { e.printStackTrace(); return;
} /** * 對應程式碼 * if (mLayout == null) { * Log.e(TAG, "Cannot smooth scroll without a LayoutManager set. " + * "Call setLayoutManager with a non-null argument."); * return; * } */ Field mLayoutField = c.getDeclaredField("mLayout"
);//根據屬性名稱,獲得類的屬性成員Field mLayoutField.setAccessible(true);//設定為可訪問狀態 LayoutManager mLayout = null; try { mLayout = (LayoutManager) mLayoutField.get(this);//獲得該屬性對應的物件 if(mLayout == null){ return; }} catch (IllegalAccessException e) { e.printStackTrace();
return; }/** * 對應程式碼 * if (mLayoutFrozen) { * return; * } */ Field mLayoutFrozen = c.getDeclaredField("mLayoutFrozen"); mLayoutFrozen.setAccessible(true); try { if((Boolean)mLayoutFrozen.get(this)){ return; } } catch (IllegalAccessException e) { e.printStackTrace(); return; } /** * 對應程式碼 * if (!mLayout.canScrollHorizontally()) { * dx = 0; * } */ if (!mLayout.canScrollHorizontally()) { dx = 0; } /** * 對應程式碼 * if (!mLayout.canScrollVertically()) { * dy = 0; * } */ if (!mLayout.canScrollVertically()) { dy = 0; } /** * 對應程式碼 * if (dx != 0 || dy != 0) { * mViewFlinger.smoothScrollBy(dx, dy); * } * 此處呼叫mViewFlinger.smoothScrollBy(dx, dy, duration);這是我們的目的。 */ Field mViewFlingerField = c.getDeclaredField("mViewFlinger"); mViewFlingerField.setAccessible(true); try { Class<?> ViewFlingerClass = null; try { //由於內部類是私有的,所以不能直接得到內部類名, //通過mViewFlingerField.getType().getName() //可以得到私有內部類的完整類名 ViewFlingerClass = Class.forName(mViewFlingerField.getType().getName());} catch (ClassNotFoundException e) { e.printStackTrace(); return; } //根據方法名,獲得我們的目標方法物件。第一個引數是方法名,後面的是該方法的入參型別。 // 注意Integer.class與int.class的不同。 Method smoothScrollBy = ViewFlingerClass.getDeclaredMethod("smoothScrollBy", int.class, int.class, int.class); smoothScrollBy.setAccessible(true);//設定為可操作狀態 if (dx != 0 || dy != 0) { Log.d("MySmoothScrollBy", "dx="+dx + " dy="+dy); try { //喚醒(呼叫)方法, // mViewFlingerField.get(this)指明是哪個物件呼叫smoothScrollBy。 // dx, dy, duration 是smoothScrollBy所需引數 smoothScrollBy.invoke(mViewFlingerField.get(this), dx, dy, duration); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } catch (NoSuchMethodException e) { e.printStackTrace(); return; } }catch (NoSuchFieldException e){; return; } }