Android反射機制

Android反射相關(guān)知識匯總

一、什么是反射機制?

JAVA反射機制是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意方法和屬性;這種動態(tài)獲取信息以及動態(tài)調(diào)用對象方法的功能稱為Java語言的反射機制。

官方文檔上介紹:反射技術(shù)通常被用來檢測和改變應(yīng)用程序在Java虛擬機中的行為表現(xiàn)。它是一個相對而言比較高級的技術(shù),通常它應(yīng)用的前提是開發(fā)者本身對于Java語言特性有很強的理解的基礎(chǔ)上。反射是一種強有力的技術(shù)特性,因此可以使得應(yīng)用程序突破一些無法企及的目的。

二、我們需要知道哪些理論基礎(chǔ)?

  • Class:Class對象是一個特殊的對象,是用來創(chuàng)建其它Java的實例,Class對象就是Java類編譯后生成的.class文件,它包含了與類有關(guān)的信息。

  • Field:Filed字段提供有關(guān)和動態(tài)訪問的信息,類或接口的單個字段。反射的字段可能是類字段或?qū)嵗侄巍?/h4>

  • Method:Method方法提供了關(guān)于單個方法的信息和訪問在類或接口上。反射的方法可能是類方法或者是一個實例方法(包括一個抽象的方法)。

  • Constructor:Constructor提供了關(guān)于某類的構(gòu)造方法的所需信息。

三、我們需要掌握哪些方法呢?

  • 獲取Class對象的幾個方法:

  1、類名.class; 不執(zhí)行靜態(tài)塊和動態(tài)構(gòu)造塊。
  2、Class.forName(path); 執(zhí)行靜態(tài)塊,不執(zhí)行動態(tài)構(gòu)造塊。
  3、對象.getClass(); 需要創(chuàng)建對象,靜態(tài)塊和動態(tài)構(gòu)造塊均會執(zhí)行。
  • 獲取類屬性Field的幾個方法:

  1、class.getField(fieldName); 只能獲取public修飾的字段
  2、class.getFields(); 獲取所有public修飾的字段的Field數(shù)組
  3、class.getDeclaredField(fieldName); 可以獲得所有字段
  4、class.getDeclaredFields(); 獲取所有字段的Field數(shù)組
  • 獲取類方法Method的幾個方法:

  1、class.getMethod(methodName); 只能獲取public修飾的方法名稱
  2、class.getMethods(); 獲取所有public修飾的方法的Method數(shù)組
  3、class.getDeclaredMethod(methodName); 可以獲得所有方法
  4、class.getDeclaredMethods(); 獲取所有方法的Method數(shù)組
  • 獲取構(gòu)造函數(shù)Constructor的幾個方法:

  1、class.getConstructor(methodName); 只能獲取public修飾的方法名稱
  2、class.getConstructors(); 獲取所有public修飾的方法的Method數(shù)組
  3、class.getDeclaredConstructor(methodName); 可以獲得所有方法
  4、class.getDeclaredConstructors(); 獲取所有方法的Method數(shù)組
  • 創(chuàng)建對象的方法

  1、Constructor.newInstance(可變參數(shù));
  eg:Persion p = (Persion)constructor.newInstance("1");
  • 設(shè)置屬性值

(1) field.set(Objkect obj,Object value);
(2) field.setInt(Objkect obj,int value);
...
(n) file.setLong(Objkect obj,long value);
  • 獲取屬性對象

(1) field.get(Object);
eg:Person p = (Persion)filed.get(對象);
  • 調(diào)用方法

這里必須注意的是當(dāng)操作的對象用private修飾的時候需要用method.setAccessible(true)來設(shè)置可以訪問到.
然后調(diào)用method.invoke(Object obj,參數(shù)),這個Object的對象必須是該類的對象.不是所謂的類對象.

四.Android能用到的地方

  • 修改TabLayout的下劃線的長度.對于TabLayout的使用這里就不必多說了,系統(tǒng)只提供了修改下劃線的高度和顏色的方法,并沒有修改長度的方法.這里就要用到反射區(qū)獲取TabLayout內(nèi)部控制長度的方法.這里只能通過設(shè)置每個Tab的Margin來控制下劃線的寬度,有可能出現(xiàn)Tab的文字被擠壓的情況,只能將就使用了.代碼如下:

Class<? extends TabLayout> tabClass = tabLayout.getClass();
     try {
         Field mTabStrip = tabClass.getDeclaredField("mTabStrip");
         mTabStrip.setAccessible(true);
        LinearLayout linearLayout = (LinearLayout) mTabStrip.get(tabLayout);
         for (int i = 0; i < linearLayout.getChildCount(); i++) {
             View child = linearLayout.getChildAt(i);
             child.setPadding(0,0,0,0);
             LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) child.getLayoutParams();
            // layoutParams.width = 300;
             layoutParams.leftMargin = 150;
             layoutParams.rightMargin = 150;
             child.setLayoutParams(layoutParams);
             child.invalidate();
         }
     } catch (NoSuchFieldException e) {
         e.printStackTrace();
     } catch (IllegalAccessException e) {
         e.printStackTrace();
     }
  • 控制Toast的顯示時間.Toast內(nèi)部類TN的設(shè)置顯示時間的代碼:

這里系統(tǒng)自帶的Toast只給了我們兩個時間的選擇SHORT_DURATION_TIMEOUT和LONG_DURATION_TIMEOUT其他的我們沒法改變.還好系統(tǒng)提供了hide方法不過在外面我們是訪問不到,這里我們也可以用到反射,大部分的操作都是Toast的內(nèi)部類TN來完成的.首先獲取到Toast的class對象,Toast內(nèi)部含有內(nèi)部類的字段(final TN mTN),這樣我們可以獲取到內(nèi)部類的對象,然后再通過內(nèi)部類的Class對象來獲取內(nèi)部類里面的hide()方法.代碼如下:

mParams.hideTimeoutMilliseconds = mDuration ==
  Toast.LENGTH_LONG ? LONG_DURATION_TIMEOUT : SHORT_DURATION_TIMEOUT;
               ...
  /**
    * schedule handleHide into the right thread
    */
   @Override
   public void hide() {
       if (localLOGV) Log.v(TAG, "HIDE: " + this);
       mHandler.obtainMessage(HIDE).sendToTarget();
   }
  try{
       Class<Toast> toastClass = Toast.class;
       Field mTN = toastClass.getDeclaredField("mTN");
       //獲取修飾符類型
       toastClass.getModifiers();
       mTN.setAccessible(true);
       Object o = mTN.get(toast);
       Class<?> aClass = o.getClass();
       Method hide = aClass.getDeclaredMethod("hide");
       hide.setAccessible(true);
       hide.invoke(o);
   } catch (NoSuchFieldException e) {
       e.printStackTrace();
   } catch (IllegalAccessException e) {
       e.printStackTrace();
   } catch (InvocationTargetException e) {
       e.printStackTrace();
   } catch (NoSuchMethodException e) {
       e.printStackTrace();
   }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 之前在網(wǎng)上找有關(guān)反射機制的資料發(fā)現(xiàn)網(wǎng)上關(guān)于這塊的資料不多,而且不太容易懂,所以試著寫一篇我自己所理解的反射機制希望...
    Lipt0n閱讀 19,317評論 19 62
  • 01、反射 主要是指程序可以訪問、檢測和修改它本身狀態(tài)或行為的一種能力。 02、反射作用 反編譯:將 class ...
    IT一書生閱讀 2,357評論 0 12
  • 文 / 西門君 圖 / 網(wǎng)絡(luò) 1. 昨天和閨蜜吃飯,她愁眉苦臉地說,最近心情糟透了。 「咋了,又失戀了?」我關(guān)切地...
    西門君不吐槽閱讀 819評論 0 1
  • 平行Amal 腹有詩書氣自華 對于那些愛看書的明星來說,他們的生活應(yīng)該更加寧靜自持,少了許多讓人心浮氣躁的情緒。當(dāng)...
    平行Amal閱讀 469評論 0 0
  • 曾以為只要努力了,就可以做好想要做的事情,只要投資了,就期待有臆想中的回報。然而其實沒有這么簡單,一周又過去了,很...
    心花怒放的日子啊閱讀 428評論 3 1

友情鏈接更多精彩內(nèi)容