Android反射メカニズム


Android反射メカニズム
 
一、反射メカニズムとは何ですか.
JAVA反射機構は運転状態において、いずれのクラスに対しても、このクラスのすべての属性と方法を知ることができる.任意のオブジェクトに対して、任意のメソッドと属性を呼び出すことができます.このような動的取得情報および動的呼び出しオブジェクトメソッドの機能をJava言語の反射メカニズムと呼ぶ.
公式ドキュメントでは、反射技術は通常、Java仮想マシンにおけるアプリケーションの動作表現を検出し、変更するために使用されます.これは比較的高度な技術であり、通常、開発者自身がJava言語の特性を強く理解していることを前提としています.反射は強力なテクノロジー機能であるため、アプリケーションが及ばない目的を突破することができます.
 
二、私たちはどんな理論の基礎を知る必要がありますか?
  • Class:Classオブジェクトは特殊なオブジェクトであり、他のJavaを作成するためのインスタンスであり、ClassオブジェクトはJavaクラスのコンパイル後に生成する.クラスに関する情報を含むclassファイル.
  • Field:Filedフィールドは、動的アクセスに関する情報、クラス、またはインタフェースの単一のフィールドを提供します.反射されるフィールドは、クラスフィールドまたはインスタンスフィールドである可能性があります.
  • Method:Methodメソッドは、単一のメソッドに関する情報とクラスまたはインタフェースへのアクセスを提供します.反射の方法は、クラスメソッドまたは抽象的なメソッドを含むインスタンスメソッドである可能性があります.
  • Constructor:Constructorは、クラスの構築方法に関する必要な情報を提供します.
  •  

  • 三、私たちはどんな方法を身につける必要がありますか?
  • Classオブジェクトを取得する方法:
  •   1、  .class;             。
      2、Class.forName(path);      ,        。
      3、  .getClass();       ,             。
    
  • クラス属性Fieldを取得するいくつかの方法:
  •   1、class.getField(fieldName);     public     
      2、class.getFields();     public      Field  
      3、class.getDeclaredField(fieldName);         
      4、class.getDeclaredFields();        Field  
    
  • クラスメソッドMethodを取得するいくつかのメソッド:
  •   1、class.getMethod(methodName);     public       
      2、class.getMethods();     public      Method  
      3、class.getDeclaredMethod(methodName);         
      4、class.getDeclaredMethods();        Method  
    
  • 構造関数Constructorを取得するいくつかの方法:
  •   1、class.getConstructor(methodName);     public       
      2、class.getConstructors();     public      Method  
      3、class.getDeclaredConstructor(methodName);         
      4、class.getDeclaredConstructors();        Method  
    
  • オブジェクトを作成する方法
  •   1、Constructor.newInstance(    );
      eg:Persion p = (Persion)constructor.newInstance("1");
    
  • 属性値
  • を設定する.
    (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(  );
    
  • 呼び出し方法
  •                private        method.setAccessible(true)        .
        method.invoke(Object obj,  ),  Object           .        .
    

     
    四.Androidが使える場所
  • TabLayoutの下線の長さを修正する.TabLayoutの使用についてはここでは言うまでもなく、システムは下線の高さと色を修正する方法しか提供しておらず、長さを修正する方法はない.ここでは反射領域がTabLayout内部の制御長を取得する方法を用いる.ここでは、各TabのMarginを設けることで下線の幅を制御するしかなく、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内部クラスTNの表示時間を設定するコード:
  • ここのシステムが持っているToastは私たちに2つの時間の選択SHOUTを与えただけです.DURATION_TIMEOUTとLONG_DURATION_TIMEOUT他の私たちは変えられない.幸いなことにシステムはhideの方法を提供したが、外ではアクセスできない.ここでは反射を使うこともでき、大部分の操作はToastの内部クラスTNで完成した.まずToastのclassオブジェクトを取得し、Toast内部に内部クラスのフィールド(final TN mTN)を含むことで、内部クラスのオブジェクトを取得することができ、その後、内部クラスのClassオブジェクトを通じて内部クラスの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 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();
       }