1、视图

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
> <Button
android:id="@+id/btn_login"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="登陆" />
<Button
android:id="@+id/btn_register"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="注册" /> </LinearLayout>

2、MainActivity

 package com.zyh.zyh_ioc;

 import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button; import com.zyh.ioc.annotation.ContentView;
import com.zyh.ioc.annotation.OnClick;
import com.zyh.ioc.annotation.ViewInject;
import com.zyh_ioc.activity.BaseActivity;
import android.widget.Toast; @ContentView(R.layout.activity_main)
public class MainActivity extends BaseActivity {
@ViewInject(R.id.btn_login)
private Button btnLogin; @ViewInject(R.id.btn_register)
private Button btnRegister; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("zyh",btnLogin.getText().toString() + "," + btnRegister.getText().toString());
} @OnClick({R.id.btn_login,R.id.btn_register})
public void Toast(View btn){
switch(btn.getId()){
case R.id.btn_login:
Toast.makeText(this, "登陆", Toast.LENGTH_SHORT).show();
break;
case R.id.btn_register:
Toast.makeText(this, "注册", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
}

3、BaseActivity

 package com.zyh_ioc.activity;

 import com.zyh.ioc.utils.InjectUtils;

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

4、InjectUtils

 package com.zyh.ioc.utils;

 import com.zyh.ioc.annotation.ContentView;
import com.zyh.ioc.annotation.EventBase;
import com.zyh.ioc.annotation.OnClick;
import com.zyh.ioc.annotation.ViewInject;
import com.zyh.ioc.proxy.ListenerInvocationHandler; import android.app.Activity;
import android.view.View; import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; //===============================================
//类的Annotation需要类对象来获取
//方法的Annotation需要方法对象来获取
//属性的Annotation需要属性对象来获取
//Annotation的Annotation需要Annotation的类对象来获取
//=============================================== public class InjectUtils {
public static void inject(Activity activity){
injectContentView(activity);
injectViews(activity);
injectEvents(activity);
} /**
* @desc 注入布局
* @param activity
*/
private static void injectContentView(Activity activity) {
Class<? extends Activity> clazz = activity.getClass();
ContentView contentView = clazz.getAnnotation(ContentView.class);
int layoutId = contentView.value();
activity.setContentView(layoutId);
} /**
* @desc 注入控件
* @param activity
*/
private static void injectViews(Activity activity) {
Class<? extends Activity> clazz = activity.getClass();
Field[] fields = clazz.getDeclaredFields();
for(Field field : fields){
ViewInject viewInject = field.getAnnotation(ViewInject.class);
if(viewInject != null){
//获取注解上的值
int viewId = viewInject.value();
Object view = activity.findViewById(viewId);//获取视图对象
try {
field.setAccessible(true);//表明私有的属性也可以设置值
field.set(activity, view);//给属性设值
} catch (Exception e) {
e.printStackTrace();
}
}
}
} /**
* @desc 注入事件
* @param activity
*/
private static void injectEvents(Activity activity) {
Class<? extends Activity> clazz = activity.getClass();
Method[] methods = clazz.getMethods();
for(Method method : methods){
Annotation[] annotations = method.getAnnotations();
for(Annotation annotation : annotations){
Class<? extends Annotation> annotationType = annotation.annotationType();//返回的是Annotation类对象
if(annotationType != null){
EventBase eventBase = annotationType.getAnnotation(EventBase.class);//获取注释的注释
if(eventBase != null){
String listenerSetter = eventBase.listenerSetter();//获取的设置监听事件的方法名
Class<?> listenerType = eventBase.listenerType();//获取监听事件的类对象
String methodName = eventBase.callBackMethod();//获取回调方法名 //下面两行代码说明:得到Annotation实例就可以获取annotation括号里的内容
/*OnClick onClick = (OnClick) annotation;
int[] xxx = onClick.value();*/
try {
//这里是利用反射获取viewIds的值
Method valueMethod = annotationType.getDeclaredMethod("value");
int[] viewIds = (int[]) valueMethod.invoke(annotation, null); //设置代理
ListenerInvocationHandler handler = new ListenerInvocationHandler(activity);
//onClick->toast
handler.addMethod(methodName, method);
//通过Proxy产生一个listenerType类型的代理对象
//listener是一个onClickListener对象
Object listener = Proxy.newProxyInstance(listenerType.getClassLoader(), new Class<?>[]{listenerType}, handler); //多个按钮要注册监听
for(int viewId : viewIds){
View view = activity.findViewById(viewId); //获取setOnClickListener方法
Method setter = view.getClass().getMethod(listenerSetter, listenerType);
//注册
setter.invoke(view, listener);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}
}

5、自定义的Annotation

1)布局的Annotation

 package com.zyh.ioc.annotation;

 import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; //指定注解使用的类的位置上
@Target(ElementType.TYPE) //编译程序将注解存储在class文件中,让虚拟机通过反射读入
@Retention(RetentionPolicy.RUNTIME)
public @interface ContentView {
int value();
}

2)findViewById的Annotation

 package com.zyh.ioc.annotation;

 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 ViewInject {
int value();
}

3)点击事件的Annotation

 package com.zyh.ioc.annotation;

 import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import android.view.View; @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@EventBase(listenerSetter = "setOnClickListener",listenerType = View.OnClickListener.class,callBackMethod = "onClick")
public @interface OnClick {
int[] value();
}
 package com.zyh.ioc.annotation;

 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 {
/**
* @desc 例如:setOnClickListener的方法名称
* @return
*/
String listenerSetter(); /**
* @desc 说明listener的类型
* @return
*/
Class<?> listenerType(); /**
* @desc listener的回调方法名称
* @return
*/
String callBackMethod();
}

6、代理类

 package com.zyh.ioc.proxy;

 import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.HashMap; public class ListenerInvocationHandler implements InvocationHandler {
private Object target; private HashMap<String, Method> methodMap = new HashMap<String, Method>(); public ListenerInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(target != null){
//执行的方法名称onClick
String methodName = method.getName();
//toast方法
Method method2 = methodMap.get(methodName);
if(method2 != null){
method2.invoke(target, args);
}
}
return null;
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
} /**
* @desc 绑定方法
* @param name
* @param method
*/
public void addMethod(String name, Method method){
methodMap.put(name, method);
}
}

代理的理解可以参考:http://blog.csdn.net/rokii/article/details/4046098

ioc构架demo的更多相关文章

  1. 话说IOC(DI)

    什么是IOC(DI) 书上的东东,因为说的太严谨,所以不太容易懂,其实也没那么复杂. 举几个例子: 1.文明点的:中午太热,不想出去吃饭,所以希望同事能帮忙带饭,现在有了点外卖平台,我们就可以直接在网 ...

  2. spring的IOC/DI功能实践

    一.写在前面: 做这个Demo主要是为了能够更好的理解Spring的原理,看再多的文章,听再多的讲解最终都最好自己去实现一遍,可以将Spring的功能分块实现,最终自然比较容易将各个功能组合起来. 这 ...

  3. Spring入门IOC和AOP学习笔记

    Spring入门IOC和AOP学习笔记 概述 Spring框架的核心有两个: Spring容器作为超级大工厂,负责管理.创建所有的Java对象,这些Java对象被称为Bean. Spring容器管理容 ...

  4. Spring.Net控制翻转、依赖注入、面向切面编程

    Spring.Net快速入门:控制翻转.依赖注入.面向切面编程 Spring.Net主要功能: 1.IoC:控制翻转(Inversion of Control)  理解成抽象工厂翻转控制:就是创建对象 ...

  5. Spring.Net快速入门:控制翻转、依赖注入、面向切面编程

    Spring.Net主要功能: 1.IoC:控制翻转(Inversion of Control)  理解成抽象工厂翻转控制:就是创建对象的权利由开发人员自己控制New,转到了由容器来控制. 2.DI: ...

  6. java后端开发三年!你还不了解Spring 依赖注入,凭什么给你涨薪

    前言 前两天和一个同学吃饭的时候同学跟我说了一件事,说他公司有个做了两年的人向他提出要涨薪资,他就顺口问了一个问题关于spring依赖注入的,那个要求涨薪的同学居然被问懵了...事后回家想了想这一块确 ...

  7. IOC:AutoFac使用demo

    使用autofac 实现依赖注入 1.引用 autofac.dll 和 autofac.configuration.dll 2.新增接口 IDAL using System; using System ...

  8. 学习Spring框架系列(一):通过Demo阐述IoC和DI的优势所在

    Spring框架最核心东西便是大名鼎鼎的IoC容器,主要通过DI技术实现.下面我通过Demo的演变过程,对比学习耦合性代码,以及解耦和的过程,并深入理解面向接口编程的真正内涵. 这个例子包括如下几个类 ...

  9. Spring之IOC/DI(反转控制/依赖注入)_入门Demo

    在平时的java应用开发中,我们要实现某一个功能或者说是完成某个业务逻辑时至少需要两个或以上的对象来协作完成,在没有使用Spring的时候,每个对象在需要使用他的合作对象时,自己均要使用像new ob ...

随机推荐

  1. swjtu 1962 A+B(模拟)

    题目链接:http://acm.swjtu.edu.cn/JudgeOnline/showproblem?problem_id=1962 问题思路:考察编程基础的问题,涉及到字符串转为数字的问题. 代 ...

  2. GLSL中的各种变量总结

    1.uint CreateShader(enum type) : 创建空的shader object; type: VERTEX_SHADER, 2.void ShaderSource(uint sh ...

  3. android项目 之 记事本(6)----- 加入手写

    想必大家都用过QQ的白板功能,里面主要有两项,一个是涂鸦功能,事实上类似于上节的画板功能,而还有一个就是手写,那记事本怎么能没有这个功能呢,今天就来为我们的记事本加入手写功能. 先上图,看看效果: 看 ...

  4. DevExpress ASP.NET 使用经验谈(7)-ASPxTreeList控件使用

    这一节,将介绍ASPxTreeList控件的使用,首先,我们增加一个标准地址库表AddressGB, 建表语句如下: CREATE TABLE [dbo].[AddressGB]( [Code] [v ...

  5. Android操作HTTP实现和服务器通信

    众所周知,Android与服务器通信通常采用HTTP通信方式和Socket通信方式,而HTTP通信方式又分get和post两种方式.至于Socket通信会在以后的博文中介绍. HTTP协议简介: HT ...

  6. CSS技巧!像table一样布局div

    摘自:http://www.cnblogs.com/hnyei/archive/2011/09/19/2181442.html 许多网页设计师都喜欢,将两个或者多个容器等高的并排放置,并在里面展示每个 ...

  7. thinkphp小技巧

    if(IS_POST) _404("页面不存在",U("index"))               //如果不是POST提交,则跳转到index.debug模 ...

  8. python成长之路15

    一:JavaScript: JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的 ...

  9. poj 2661 Factstone Benchmark

    /** 大意: 求m!用2进制表示有多少位 m! = 2^n 两边同时取对数 log2(m!) = n 即 log2(1) + log2(2)+log2(3)+log2(4)...+log2(m) = ...

  10. Log Collect

    http://ossectools.blogspot.com/2011/03/comprehensive-log-collection.html https://www.hacking-lab.com ...