IoC의 간단한 사용

6821 단어 Android
1. 반사 관련api
API
묘사
getClass()
클래스 가져오기
getName()
클래스의 전체 이름을 얻습니다.
getAnnotation(xxx.class)
메모 가져오기
getMethod()
모든 (부류 포함)public 방법 얻기
getFields()
모든 (부모 클래스 포함)public 속성 획득
invoke(xx,yy)
실행 방법
getDeclaredMethods()
현재 클래스의 모든 방법을 가져옵니다 (private 포함)
getDeclaredFields()
현재 클래스의 모든 속성을 가져옵니다 (private 포함)
annotationType()
메모 유형 가져오기
getConstructors()
클래스의public 형식을 가져오는 구조 방법
getConstructor(Class[] parameterTypes)
클래스의 특정 구조 방법을 얻고parameterTypes 매개 변수는 구조 방법의 매개 변수 유형을 지정합니다.
newInstance()
클래스의 파라미터가 없는 구조 방법을 통해 클래스의 대상을 만듭니다.
setAccessible(true)
Java 액세스 권한 확인 메커니즘 취소
주해
1. @Target 메모의 역할 목표
type
역할 목표
ElementType.TYPE
인터페이스, 클래스, 열거, 주석
ElementType.FIELD
필드, 열거된 상수
ElementType.METHOD
메서드
ElementType.PARAMETER
메소드 매개변수
ElementType.CONSTRUCTOR
구조 함수
ElementType.LOCAL_VARIABLE
국부 변수
ElementType.ANNOTATION_TYPE
주해
ElementType.PACKAGE
싸다
Android ElementType APIs
2. @Retention: 메모의 보존 위치
type
역할 목표
RetentionPolicy.SOURCE
주석은 원본 코드에만 존재하며,class 바이트 파일에는 포함되지 않습니다
RetentionPolicy.CLASS
기본 보존 정책, 주석은class 바이트 파일에 존재하지만 실행할 때 얻을 수 없습니다
RetentionPolicy.RUNTIME
주석은class 바이트 파일에 존재하며, 실행할 때 반사로 얻을 수 있습니다
Android RetentionPolicy APIs
3. 프록시 Proxy
참조[Java 동적 에이전트]
4. LayoutView
주석을 통해 Activity에 레이아웃 파일 자동 추가
주석: LayoutView
@Target(ElementType.TYPE)//      ... 
@Retention(RetentionPolicy.RUNTIME)//             
public @interface LayoutView {
    int value();
}

Activity에서 사용:
@LayoutView(R.layout.activity_main)
public class MainActivity extends BaseActivity implements View.OnClickListener {
    //...
}

Activity에 반사하여 레이아웃 파일 추가하기
/**
 *  Activity    
 * @param activity
 */
private static void bindLayout(Activity activity) {
    Class extends Activity> clazz = activity.getClass();
    //    
    LayoutView layoutView = clazz.getAnnotation(LayoutView.class);
    if (layoutView!=null){
        int layoutId = layoutView.value();
        try {
            Method method = clazz.getMethod("setContentView", int.class);
            method.invoke(activity,layoutId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

5. BindView
메모를 통해 자동으로 findViewById
메모:BindView
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BindView {
    int value();
}

Activity에서 사용:
@BindView(R.id.textView)
private TextView textView;

@BindView(R.id.button)
private TextView button;

반사를 통해 콜아웃에 대한 View 지정값 추가
/**
 *  Activity   View  
 * @param activity
 */
private static void bindViews(Activity activity) {
    Class extends Activity> clazz = activity.getClass();
    //         
    Field[] fields = clazz.getDeclaredFields();
    for (Field field: fields) {
        //       
        BindView bindView = field.getAnnotation(BindView.class);
        if (bindView!=null){//  InjectView           
            //  view id
            int viewId = bindView.value();
            try {
                Method method = clazz.getMethod("findViewById", int.class);
                //  view
                Object view = method.invoke(activity, viewId);
                //  Java      
                field.setAccessible(true);
                // Activity        
                field.set(activity,view);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

6. 이벤트 귀속
1. @OnClick 메모를 통해 View의 클릭 이벤트 설정
@OnClick(R.id.textView)
public void aaabbbccc(View view){
    Toast.makeText(this,"          ",Toast.LENGTH_LONG).show();
}

2. 메모 @OnClick
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@EventBase(listenerSetter = "setOnClickListener",listenerType = View.OnClickListener.class,callBackFunction = "onClick")
public @interface OnClick {
    int[] value();
}

3. 메모 @OnClick에 사용되는 메모 @EventBase
@Target(ElementType.ANNOTATION_TYPE)//       
@Retention(RetentionPolicy.RUNTIME)
public @interface EventBase {

    //1、setOnxxxListener()
    String listenerSetter();

    //2、     
    Class> listenerType();

    //3、     onClick(View view)
    String callBackFunction();
}

4. 이벤트 주입 핵심 코드:
/**
 *     
 * @param activity
 */
private static void bindEvent(Activity activity) {
    Class extends Activity> clazz = activity.getClass();
    //          
    Method[] methods = clazz.getDeclaredMethods();
    for (Method method : methods) {
        //         (      )
        Annotation[] annotations = method.getAnnotations();
        //       
        for (Annotation annotation:annotations) {//OnClick  
            if (annotation==null)return;
            //      
            Class extends Annotation> annotationType = annotation.annotationType();
            if (annotationType!=null){
                //  OnClick    EventBase  
                EventBase eventBase= annotationType.getAnnotation(EventBase.class);
                if (eventBase==null)return;
                String callBackListener = eventBase.callBackFunction();//onClick
                String listenerSetter = eventBase.listenerSetter();//setOnClickListener
                Class> listenerType = eventBase.listenerType();// View.OnClickListener.class

                try {
                    Method declaredMethod = annotationType.getDeclaredMethod("value");
                    int[] viewIds = (int[]) declaredMethod.invoke(annotation);

                    ListenerInvocationHandler listenerInvocationHandler = new ListenerInvocationHandler(activity);
                    listenerInvocationHandler.addMethod(callBackListener,method);
                    Object listener = Proxy.newProxyInstance(listenerType.getClassLoader(), new Class[]{listenerType}, listenerInvocationHandler);

                    for (int id:viewIds) {
                        //    View
                       View view= activity.findViewById(id);
                       //  View setOnClickListener  
                       Method onClickListenerMethod = view.getClass().getMethod(listenerSetter,listenerType);
                       //  setOnClickListener  
                         onClickListenerMethod.invoke(view,listener);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    }

}

github 소스 링크

좋은 웹페이지 즐겨찾기