IOC架构设计之事件注入

MainActivity

@ContentView(R.layout.activity_main)
public class MainActivity extends BaseActivity{
    public static  final String TAG="dongnao";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        ListView listView=null;
//        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
//            @Override
//            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//
//            }
//        });
    }
    public  void itemClick(AdapterView<?> parent, View view, int position, long id)
    {

    }
    @OnClick({R.id.text,R.id.text2})
    public void onClick(View view)
    {
        Toast.makeText(this,"单击",Toast.LENGTH_SHORT).show();
    }
    @OnLongClick({R.id.text2})
    public  boolean onLongClick(View view)
    {
        Toast.makeText(this,"长按",Toast.LENGTH_SHORT).show();
        return true;
    }
}

ContentView

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

EventBase

/**
 * Created by Administrator on 2017/2/27 0027.
 * 设计目的是 对所有的事件点击 进行扩展
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface EventBase {
    /**
     * 设置监听的方法
     * @return
     */
    String listenerSetter();

    /**
     * 事件类型
     * @return
     */
    Class<?> listenerType();
    /**
     * 回调方法
     * 事件被触发后,执行回调方法名称
     */
    String callBackMethod();
}
OnClick

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@EventBase(listenerSetter = "setOnClickListener",
        listenerType = View.OnClickListener.class,
        callBackMethod = "onClick")
public @interface OnClick
{
    /**
     * 哪些kongji控件id 进行设置点击事件
     * @return
     */
    int[] value();
}

OnItemClick

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@EventBase(listenerSetter = "setOnClickListener",
        listenerType = View.OnClickListener.class,
        callBackMethod = "onClick")
public @interface OnClick
{
    /**
     * 哪些kongji控件id 进行设置点击事件
     * @return
     */
    int[] value();
}

OnLongClick

/**
 * Created by Administrator on 2017/2/27 0027.
 * 设置长按事件
 *
 *  textView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {

return false;
}
});
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@EventBase(listenerSetter = "setOnLongClickListener",
        listenerType = View.OnLongClickListener.class,callBackMethod = "onLongClick")
public @interface OnLongClick {
    int[] value() default -1;
}

ListenerInvocationHandler

public class ListenerInvocationHandler implements InvocationHandler{
    //activity   真实对象
    private Context context;
    private Map<String,Method> methodMap;

    public ListenerInvocationHandler(Context context, Map<String, Method> methodMap) {
        this.context = context;
        this.methodMap = methodMap;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String name=method.getName();
        //决定是否需要进行代理
        Method metf=methodMap.get(name);

        if(metf!=null)
        {
            return  metf.invoke(context,args);
        }else
        {
            return method.invoke(proxy,args);
        }
    }
}

BaseActivity

public class BaseActivity  extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        InjectUtils.inject(this);
    }
}

InjectUtils

/**
 * Created by Administrator on 2017/2/24 0024.
 * 第三方容器
 *
 */

public class InjectUtils {
    public  static  void inject(Context context)
    {
        injectLayout(context);
        injectView(context);
        injectEvents(context);
    }

    /**
     * 注入事件
     * @param context
     */
    private static void injectEvents(Context context) {
        Class<?> clazz=context.getClass();
        //获取Activity里面 所有方法
        Method[] methods=clazz.getDeclaredMethods();
        //遍历Activity所有方法
        for (Method method:methods)
        {
            //获取方法上所有的注解
            Annotation[]  annotations=method.getAnnotations();
            for(Annotation annotation:annotations)
            {
                //获取注解 anntionType   OnClick  OnLongClck
                Class<?> anntionType=annotation.annotationType();
                //获取注解的注解   onClick 注解上面的EventBase
                EventBase eventBase=anntionType.getAnnotation(EventBase.class);
                if(eventBase==null)
                {
                    continue;
                }
                /*
                开始获取事件三要素  通过反射注入进去
                1 listenerSetter  返回     setOnClickListener字符串
                 */
                String listenerSetter=eventBase.listenerSetter();
                //得到 listenerType--》 View.OnClickListener.class,
                Class<?> listenerType=eventBase.listenerType();
                //callMethod--->onClick
                String callMethod=eventBase.callBackMethod();
                //方法名 与方法Method的对应关心
                Map<String,Method> methodMap=new HashMap<>();

                methodMap.put(callMethod,method);

                try {
                    Method valueMethod=anntionType.getDeclaredMethod("value");
                    int[] viewIds= (int[]) valueMethod.invoke(annotation);
                    for (int viewId:viewIds)
                    {
                        //通过反射拿到TextView
                        Method findViewById=clazz.getMethod("findViewById",int.class);
                        View view= (View) findViewById.invoke(context,viewId);
                        if(view==null)
                        {
                            continue;
                        }
                        /*
                        listenerSetter  setOnClickLitener
                        listenerType   View.OnClickListener.class
                         */
                        Method setOnClickListener=view.getClass().getMethod(listenerSetter,listenerType);

                        ListenerInvocationHandler handler=new ListenerInvocationHandler(context,methodMap);
//                        proxyy已经实现了listenerType接口
                        Object proxy= Proxy.newProxyInstance
                                (listenerType.getClassLoader(),
                                        new Class[]{listenerType},handler);
                        /**
                         * 类比 于  textView.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                        }
                        });
                         */
                        setOnClickListener.invoke(view,proxy);
                    }
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }

            }

        }
    }

    public static void injectView(Context context)
    {
        Class<?> aClass=context.getClass();
        //获取到MainActivity里面所有的成员变量 包含 textView
        Field[] fields=aClass.getDeclaredFields();
        for (Field field:fields)
        {
            //得到成员变量的注解
            ViewInject viewInject=field.getAnnotation(ViewInject.class);
            if(viewInject!=null)
            {
                //拿到id  R.id.text
                int valueId=viewInject.value();
                try {
                    //View view=activity.findViewById()
                    Method method=aClass.getMethod("findViewById",int.class);
                    //反射调用方法
                    View view= (View) method.invoke(context,valueId);
                    field.setAccessible(true);
                    field.set(context,view);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }

    }


    public static void injectLayout(Context context)
    {
        int layoutId=0;
        Class<?> clazz=context.getClass();
        //拿到MainActivity类上面的注解
        ContentView contentView=clazz.getAnnotation(ContentView.class);
        if (contentView != null ) {
            layoutId=contentView.value();
            try {
                Method method=clazz.getMethod("setContentView",int.class);
                method.invoke(context,layoutId);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值