android 用java反射修改Activity的元件view的佈局或者屬性
阿新 • • 發佈:2019-01-23
原因:正所謂技術來源於需求,同時推動需求 , 研究的出發點是,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