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. rman备份优化思路

    本章不讲rman备份原理.仅仅提供一些思路 1.oracle11g 选择压缩算法为中级: 2.添加rman备份的通道. 以上两种做法.添加CPU的利用率,降低IO 3.指定rate參数 这个rate和 ...

  2. poj 2411 Mondriaan's Dream 轮廓线dp

    题目链接: http://poj.org/problem?id=2411 题目意思: 给一个n*m的矩形区域,将1*2和2*1的小矩形填满方格,问一共有多少种填法. 解题思路: 用轮廓线可以过. 对每 ...

  3. BI商业智能项目中的若干风险要素

    BI商业智能项目应在 “业务驱动,总体规划,统一设计,分期实施” 的总体设计原则下分期实施,采取Agile BI方法论迭代开展,先确保核心功能满足客户需求,在总体规划下不断完善整个系统,以提高可交付性 ...

  4. ORACLE分科目统计每科前三名的学生的语句

    有个成绩表 score(student_no,Subject_no,Score)分别为学号,课程号,成绩.我想用语句查询出每科的前三名学生的学号,请各位高手教教小弟 1.创建测试语句:create t ...

  5. 前端笔试面试中的常用知识点总结(CSS)

    1.CSS选择器的优先级!important  > 内联 > id选择器 > 类选择器 > 标签选择器多个类选择器叠加(256)之后的优先级大于一个id选择器!importan ...

  6. 下载文件夹里面的所有文件,并压缩成.zip压缩包的形式

    http://www.aspsnippets.com/Articles/Download-multiple-files-as-Zip-Archive-File-in-ASPNet-using-C-an ...

  7. [译]Stairway to Integration Services Level 3 - 增量导入数据

    让我们打开之前的项目:My_First_SSIS_Project_After_Step_2.zip 之前项目中我们已经向dbo.contact 导入了19972行,如果再次执行包会重复导入,让我们来解 ...

  8. js 乱码解决方案

    如果网页编码规则是utf-8,即在网页头部中可以看到如下代码: 那么js文件中如果有中文字,调用输出时就会出现乱码.解决此个问题的办法如下: 即在引用javascript输出的地方加上charset= ...

  9. 【MFC相关】图片显示

    CPaintDC dc(this); if (!m_hBitmap) return; image.Attach(m_hBitmap); CRect rect; GetClientRect(&r ...

  10. Oracle 11g New 热补丁

    热补丁:概览 对于Oracle 实例上的bug 修复或诊断补丁程序,热补丁 可以执行以下操作: • 安装 • 启用 • 禁用 热补丁:概览 使用热补丁可以安装.启用和禁用 正在运行的 活动Oracle ...