Java筆記:[反射篇] 利用反射,獲取類中的私有內部類物件,並呼叫該物件的方法
阿新 • • 發佈:2018-12-26
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;
}
}