原因:正所谓技术来源于需求,同时推动需求 , 研究的出发点是,PM发现app的某一个view的组件有些问题,view坐标或者颜色、字体大小等,需要rd去修改,但是呢这个组件是第三方的sdk中内置,并没有提供 对应的接口或者方法,怎么办?
以前是这样的:
方法:反射 。。。反射。。。发射,重要的事情说三遍
具体操作步骤:
反射的原理不必多说了! 网上的demo成堆!
1.拿到当前要修改的Activity的instance实例对象,反射的时候需要用到这个对象,注意这个对象是要展示的那个快销
引用自:点击打开链接
public static Activity getActivity() {
Class activityThreadClass = null;
try {
activityThreadClass = Class.forName("android.app.ActivityThread");
Object activityThread = activityThreadClass.getMethod("currentActivityThread").invoke(null);
Field activitiesField = activityThreadClass.getDeclaredField("mActivities");
activitiesField.setAccessible(true);
Map activities = (Map) activitiesField.get(activityThread);
for (Object activityRecord : activities.values()) {
Class activityRecordClass = activityRecord.getClass();
Field pausedField = activityRecordClass.getDeclaredField("paused");
pausedField.setAccessible(true);
if (!pausedField.getBoolean(activityRecord)) {
Field activityField = activityRecordClass.getDeclaredField("activity");
activityField.setAccessible(true);
Activity activity = (Activity) activityField.get(activityRecord);
return activity;
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
2. 反射走起来,设置属性
try {
Activity temp = getActivity();
Class clazz = temp.getClass();
Field idFid = clazz.getDeclaredField("h");
idFid.setAccessible(true);
RelativeLayout relativeLayout = (RelativeLayout) idFid.get(temp);
Field bFid = clazz.getDeclaredField("b");
bFid.setAccessible(true);
TextView s = (TextView) relativeLayout.findViewById(bFid.getInt(temp));
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) s.getLayoutParams();
Field aFid = clazz.getDeclaredField("a");
aFid.setAccessible(true);
layoutParams.width = -2;
layoutParams.height = -1;
layoutParams.addRule(RelativeLayout.RIGHT_OF, aFid.getInt(temp));
Button back = (Button) relativeLayout.findViewById(aFid.getInt(temp));
RelativeLayout.LayoutParams layoutParamsBtn = (RelativeLayout.LayoutParams) back.getLayoutParams();
layoutParamsBtn.width = DeviceUtils.dip2px(temp, 40);
back.setLayoutParams(layoutParamsBtn);
s.setLayoutParams(layoutParams);
} catch (Exception e) {
e.printStackTrace();
}
3. 走几步看看??效果图
4. h 、 a、b等都是成员变量混淆之后变量
设置之后记得:back.setLayoutParams(layoutParamsBtn); 否则不生效哦,原因自己去看view源码去吧!
RelativeLayout的代码布局:layoutParams.addRule(RelativeLayout.RIGHT_OF, aFid.getInt(temp)); 第二个参数是anchor,就是相对的组件ID