天天看點

Aop事件注入

package inject;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ContentView {
    int value();
}
           

ContenView注解

package inject;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InJectView {
    int value();
}
           

InJect注解

package inject;

import android.view.View;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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


package inject;

import android.view.View;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@EventBase(listenerSetter = "setOnLongClickListener",listenerType = View.OnLongClickListener.class,callback = "onLongClick")
public @interface OnLongClick {
    int[] value();
}
           

onClick  onLongClick注解

package inject;

import android.view.View;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface EventBase {

    String listenerSetter();

    Class<?> listenerType();

    String callback();

}
           

事件注解 setOnClickListener View.OnClickListener,onClick

package inject;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.HashMap;

public class ListenerInvolcationHandler implements InvocationHandler {

    private Object target;

    public ListenerInvolcationHandler(Object target) {
        this.target = target;
    }

    private HashMap methodMap = new HashMap();
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if(target != null){
            method = (Method) methodMap.get(method.getName());
            if(method != null){
                method.setAccessible(true);
                return method.invoke(target,args);
            }
        }
        return null;
    }

    public void addMethod(String methodName,Method method){
        methodMap.put(methodName,method);
    }
}
           
package inject;

import android.app.Activity;
import android.view.View;

import com.example.aopdemo.BaseActivity;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class InjectManager {
    //regesit
    public static void inJect(Activity baseActivity) {
        //layout
        injectLayout(baseActivity);

        //views
        injectViews(baseActivity);

        //events
        injectEvent(baseActivity);
    }

    private static void injectEvent(Activity baseActivity) {

        //registEvent
        Class<? extends Activity> clazz = baseActivity.getClass();
        Method[] methods = clazz.getDeclaredMethods();
        if(methods != null&&methods.length >0){
            for(int i = 0;i<methods.length;i++){
                Method method = methods[i];
               Annotation[] annotations = method.getAnnotations();
               for(Annotation annotation:annotations){
                   Class<? > annotationType = annotation.annotationType();
                   if(annotationType != null){
                       EventBase eventBase = annotationType.getAnnotation(EventBase.class);
                       if(eventBase != null){
                           String listenerSetter = eventBase.listenerSetter();
                           Class<?> listenerType = eventBase.listenerType();
                           String callBack = eventBase.callback();
                           ListenerInvolcationHandler listenerInvolcationHandler = new ListenerInvolcationHandler(baseActivity);
                           Object listener = Proxy.newProxyInstance(listenerType.getClassLoader(),new Class[]{listenerType},listenerInvolcationHandler);
                           listenerInvolcationHandler.addMethod(callBack,method);
                           try {
                               Method value = annotationType.getDeclaredMethod("value");
                               try {
                                   int[] ids = (int[]) value.invoke(annotation);
                                   for(int viewId:ids){
                                       View view = baseActivity.findViewById(viewId);
                                       Method setter = view.getClass().getMethod(listenerSetter,listenerType);
                                       setter.invoke(view,listener);

                                   }
                               } catch (IllegalAccessException e) {
                                   e.printStackTrace();
                               } catch (InvocationTargetException e) {
                                   e.printStackTrace();
                               }
                           } catch (NoSuchMethodException e) {
                               e.printStackTrace();
                           }
                       }
                   }
               }
            }
        }

    }



    private static void injectViews(Activity baseActivity) {
        Class<? extends Activity> clazz = baseActivity.getClass();

        //get all fields
        Field[] fields = clazz.getDeclaredFields();
        if(fields !=  null&&fields.length > 0){
            for(int i = 0;i< fields.length;i++){
                Field field = fields[i];
                InJectView inJectView = field.getAnnotation(InJectView.class);
                if(inJectView != null){
                    try {
                        Method method = clazz.getMethod("findViewById", int.class);
                        int viewId = inJectView.value();
                        try {
                            View view = (View) method.invoke(baseActivity,viewId);
                            field.setAccessible(true);
                            field.set(baseActivity,view);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        } catch (InvocationTargetException e) {
                            e.printStackTrace();
                        }
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    }
                }
            }
        }


        
    }

    private static void injectLayout(Activity baseActivity) {
        Class<? extends Activity> clazz = baseActivity.getClass();

        ContentView contentView = clazz.getAnnotation(ContentView.class);

        if(contentView != null){
            int layout = contentView.value();
            try {
                Method method = clazz.getMethod("setContentView", int.class);
                try {
                    method.invoke(baseActivity,layout);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        
    }
}
           

事件注解管理

package com.example.aopdemo;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;

import inject.InjectManager;


public class BaseActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        InjectManager.inJect(this);

    }
}


package com.example.aopdemo;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import inject.ContentView;
import inject.InJectView;
import inject.OnClick;
import inject.OnLongClick;

@ContentView(R.layout.activity_main)
public class MainActivity extends BaseActivity {

    @InJectView(R.id.bt)
    private Button mBt;

    @InJectView(R.id.tv)
    private TextView mTv;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mBt.setText("test button");
        mTv.setText("test text");
    }

    @OnClick({R.id.bt,R.id.tv})
    private void onClick(View view){
        switch (view.getId()){
            case R.id.bt:
                Log.d("zpb","onClick button");
                break;
            case R.id.tv:
                Log.d("zpb","onClick TextView");
                break;
        }

    }

    @OnLongClick({R.id.bt})
    private boolean onLongClick(View view){
        switch (view.getId()){
            case R.id.bt:
                Log.d("zpb","onLongClick button");

                break;
        }
        return true;
    }

    private void setListener(){

    }


}
           

測試Demo