1. 程式人生 > >android註解與反射

android註解與反射

5. 限定註解的使用範圍@Target

TYPE: 用於類,介面,列舉但不能是註解 
FIELD: 欄位上,包括列舉值 
METHOD: 方法,不包括構造方法 
PARAMETER: 方法的引數 
CONSTRUCTOR: 構造方法 
LOCAL_VARIABLE: 本地變數或catch語句 
ANNOTATION_TYPE: 註解型別(無資料) 
PACKAGE: Java包 

6. 註解保持性策略RetentionPolicy

1) RUNITIME: 保留在編譯的類檔案中,並在第一次載入類時讀取它; 
2) CLASS: 保留在編譯後的類檔案中,但在執行時忽略它; 
3) SOURCE: 按規定使用註解,但並不將它保留在編譯後的類檔案中; 

(1)自定義註解

1) 先定義佈局檔案注入:

//註解的作用域在類上
@Target(ElementType.TYPE)
//讓保持性策略為執行時態,將註解編碼到class檔案中,讓虛擬機器讀取
@Retention(RetentionPolicy.RUNTIME)
public @interface ContentView {
    int value();//使用時直接@ContentView(R.layout.xxx)指定的R.layout.xxx就是佈局檔案,會自動注入佈局檔案
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2) 佈局中控制元件注入檔案

@Target(ElementType.FIELD)
@Retention
(RetentionPolicy.RUNTIME) public @interface ViewInject { int value(); }
  • 1
  • 2
  • 3
  • 4
  • 5

3) 控制元件的點選響應注入檔案

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OnClick {
    int[] value();
}

(2) 使用自定義註解

對一個成員變數使用@BindView註解,並傳入一個View Id, ButterKnife就能夠找到對應的View,並自動進行轉換成所需控制元件型別。

@Contentview(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
    @ViewInject(R.id.name_tv)
    TextView name_tv;
    @ViewInject(R.id.tu_iv)
    ImageView tu_iv;
    @Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
        ViewInjectUtils.getutil(this);
    

    }

    //方法名字任意起
@OnClick({R.id.bt,R.id.bt1})
    public void ni(View view){
           switch (view.getId()) {
                 case R.id.bt:
                        Toast.makeText(MainActivity.this,"你猜",Toast.LENGTH_SHORT).show();
                    break;
                case R.id.bt1:
                    Toast.makeText(MainActivity.this,"啥都不會",Toast.LENGTH_SHORT).show();
                    break;
                 }

    }

(3) 通過反射機制獲取註解引數

1) 佈局檔案獲取

private static void jnectContentView(Activity activity) {
        //獲取activity的類例項
        Class<? extends Activity> clazz = activity.getClass();
        //獲取到activity的ContentView註解
        ContentView contentView = clazz.getAnnotation(ContentView.class);
        if (contentView != null) {
            //如果activity上面存在這個註解的話,就取出這個註解對應的value值,就是前面設定的佈局
            int layoutId = contentView.value();
            try {
                //利用反射呼叫setContentView方法,完成注入
                Method setViewMethod = clazz.getMethod("setContentView", int.class);
                setViewMethod.invoke(activity, layoutId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2) 控制元件獲取實現

 private static void injectView(Activity activity) {
        Class<? extends Activity> clazz = activity.getClass();
        //獲取activity的所有成員變數
        Field[] fields = clazz.getDeclaredFields();
        //遍歷成員變數,獲取成員變數上的ViewInject註解
        for (Field field : fields) {
            //獲取欄位上面的註解物件,同有則繼續下一個欄位
            ViewInject viewInject = field.getAnnotation(ViewInject.class);
            if (viewInject != null) {
                //獲取ViewInject註解的View的id
                int viewId = viewInject.value();
                //獲取控制元件
                View view = activity.findViewById(viewId);
                try {
                    //設定field為可訪問,就算私有的也能訪問到
                    field.setAccessible(true);
                    //將該控制元件設定給field物件
                    field.set(activity, view);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }

3)控制元件點選響應

//點選事件
public static void injectEvent(final Activity activity) {
    //獲取所有的方法
Method[] methods = activity.getClass().getDeclaredMethods();
    for (final Method method : methods) {
        if (method!=null&&methods.length>0){
            //暴力反射
method.setAccessible(true);
            //OnClick為註解的類名
OnClick click = method.getAnnotation(OnClick.class);
            if (click!=null){
                int[] value = click.value();
                for (int i : value) {
                    //獲取每一個view
final View viewById = activity.findViewById(i);
                    //給每個view都設定點選事件
viewById.setOnClickListener(new View.OnClickListener() {
                        @Override
public void onClick(View v) {
                            try {
                                method.invoke(activity,viewById);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }

            }
        }
    }
}

參考:http://blog.csdn.net/smileiam/article/details/72771634   檔案獲取和控制元件獲取

https://www.cnblogs.com/YukiKun/p/5143937.html   點選事件

http://blog.csdn.net/tongseng/article/details/72859162

相關推薦

android註解反射

5. 限定註解的使用範圍@Target TYPE: 用於類,介面,列舉但不能是註解  FIELD: 欄位上,包括列舉值  METHOD: 方法,不包括構造方法  PARAMETER: 方法的引數  CONSTRUCTOR: 構造方法  LOCAL_VARIABLE: 本

Android之“註解反射

原文連結:理解Android中的註解與反射 反射 Java反射(Reflection)定義 Java反射機制是指在執行狀態中 對於任意一個類,都能知道這個類的所有屬性和方法; 對於任何一個物件,都能夠呼叫它的任何一個方法和屬性; 這樣動態獲取新的以及動態呼叫物件方法

理解Android中的註解反射

前言 最近一段時間在研究EventBus和Retrofit 的過程中,都遇到了註解這個概念。由於在學習Java的時候對這方面沒有深入瞭解過,所以看起相關的程式碼來,總會有點不知其所以然,這裡就註解和反射的使用做一下總結。 這裡我們先從反射說起,瞭解了反射的意

Java註解反射應用的小例子

1.功能介紹    小例子主要完成以下功能,通過Java反射獲取SQL語句,使用MyBatis傳入SQL語句,將資料插入到資料庫中2.程式碼講解2.1 自定義註解    首先看一個自定義註解,在此例子中我自定義了兩個註解,一個叫DBTable,另一個是DBColumn。   

Java 之路 (十九) -- 註解(語法、預定義註解、元註解、重複註解註解反射

前言 官方註解的定義如下: 註解(一種元資料形式)提供有關不屬於程式本身的程式的資料。註解對它們註解的程式碼的操作沒有直接影響。 註解有許多用途,其中包括: 編譯器的資訊 - 編譯器可以使用註解來檢測錯誤或抑制警告。 編譯

Android開發之反射註解

反射 類型別Class的使用 類型別Class的例項獲取方式有一下三種 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

android 自定義註解 通過反射獲取註解屬性值

參考文章:http://xuwenjin666.iteye.com/blog/1637247 1.自定義註解 package cn.veji.hibernate.po; import java.lang.annotation.ElementType; import ja

JAVA反射 Android藍芽反射

  要想理解反射的原理,首先要了解什麼是型別資訊。Java讓我們在執行時識別物件和類的資訊,主要有2種方式:一種是傳統的RTTI,它假定我們在編譯時已經知道了所有的型別資訊;另一種是反射機制,它允許我們在執行時發現和使用類的資訊。 1、Class物件   理解RTTI在Java中的工作原

Android中的自定義註解反射實現-執行時註解

預備知識: Java註解基礎 Java反射原理 Java動態代理 一、佈局檔案的註解 我們在Android開發的時候,總是會寫到setContentView方法,為了避免每次都寫重複的程式碼,我們需要使用註解來代替我們做這個事情,只需要在類Activity上

android 自定義註解 通過反射獲取註解屬性值

1.自定義註解 package cn.veji.hibernate.po; import java.lang.annotation.ElementType; import java.

Android中通過反射來設置Toast的顯示時間

ring margin ner manage etc short 延遲 lln sse 這個Toast的顯示在Android中的用途還是非常大的,同一時候我們也知道toast顯示的時間是不可控的。我們僅僅能改動他的顯示樣式和顯示的位置,盡管他提供了一個顯示時間的設置方法

Android setTag()getTag(),set多個setTag()

data- sta har car etc bsp ring 我們 () 首先我們要知道setTag方法是幹什麽的,SDK解釋為 Tags Unlike IDs, tags are not used to identify views. Tags are es

JAVA序列化反射

技術分享 ges img .cn logs 技術 序列化 com -1 JAVA序列化與反射

android:padding android:margin的差別

track line trac andro 邊框 pop col ack ria android:padding Padding 為內邊框,指該控件內部內容,如文本/圖片距離該控件的邊距 android:margin Margin 為外邊框,指該控件距離邊

Android BLE終端通信(三)——client服務端通信過程以及實現數據通信

.sh 沒有 indexof 實例 解析 rip listview filter @override Android BLE與終端通信(三)——client與服務端通信過程以及實現數據通信 前面的終究僅僅是小知識點。上不了臺面,也僅僅能算是起

【Java基礎】RTTI反射之Java

start auth try dword star sse from tac sed 1 ; Example assembly language program -- 2 ; Author: Karllen 3 ; Date: revised 05/2014

android FragmentActivity交互,互相發數據(附圖具體解釋)

oncreate @+ targe save inflate find enter 提交 ransac 筆者最近看官方training。發現了非常多實用又好玩的知識。當中。fragment與Activity通信就是一個。 fragment與Activity通信主要

Java註解反射得到註解

-a hide for dcb his port ges cnblogs 類名 Class類的方法 f package com.part1; /** * * @author pc * */ public class Studen

使用Android註解來改善代碼

反饋 sources ret found 可能 ocs not ber 顯示 昨晚看到一篇好文章。然後是英文的。所以決定翻譯分享給大家。這是原文鏈接:http://www.michaelevans.org/blog/2015/07/14/improvin

關於mac android studio svn 解除關聯後 無法再次share (Subversion) 的解決辦法

pre lac lan n) con oid directory ppi files Android studio 把工程share 到 svn 上面,可是一不小心忘了 ignore files 的設置,結果沒辦法,把svn 上的刪掉再重新share 一次,先接觸本地代碼與