ioc构架demo
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的更多相关文章
- 话说IOC(DI)
什么是IOC(DI) 书上的东东,因为说的太严谨,所以不太容易懂,其实也没那么复杂. 举几个例子: 1.文明点的:中午太热,不想出去吃饭,所以希望同事能帮忙带饭,现在有了点外卖平台,我们就可以直接在网 ...
- spring的IOC/DI功能实践
一.写在前面: 做这个Demo主要是为了能够更好的理解Spring的原理,看再多的文章,听再多的讲解最终都最好自己去实现一遍,可以将Spring的功能分块实现,最终自然比较容易将各个功能组合起来. 这 ...
- Spring入门IOC和AOP学习笔记
Spring入门IOC和AOP学习笔记 概述 Spring框架的核心有两个: Spring容器作为超级大工厂,负责管理.创建所有的Java对象,这些Java对象被称为Bean. Spring容器管理容 ...
- Spring.Net控制翻转、依赖注入、面向切面编程
Spring.Net快速入门:控制翻转.依赖注入.面向切面编程 Spring.Net主要功能: 1.IoC:控制翻转(Inversion of Control) 理解成抽象工厂翻转控制:就是创建对象 ...
- Spring.Net快速入门:控制翻转、依赖注入、面向切面编程
Spring.Net主要功能: 1.IoC:控制翻转(Inversion of Control) 理解成抽象工厂翻转控制:就是创建对象的权利由开发人员自己控制New,转到了由容器来控制. 2.DI: ...
- java后端开发三年!你还不了解Spring 依赖注入,凭什么给你涨薪
前言 前两天和一个同学吃饭的时候同学跟我说了一件事,说他公司有个做了两年的人向他提出要涨薪资,他就顺口问了一个问题关于spring依赖注入的,那个要求涨薪的同学居然被问懵了...事后回家想了想这一块确 ...
- IOC:AutoFac使用demo
使用autofac 实现依赖注入 1.引用 autofac.dll 和 autofac.configuration.dll 2.新增接口 IDAL using System; using System ...
- 学习Spring框架系列(一):通过Demo阐述IoC和DI的优势所在
Spring框架最核心东西便是大名鼎鼎的IoC容器,主要通过DI技术实现.下面我通过Demo的演变过程,对比学习耦合性代码,以及解耦和的过程,并深入理解面向接口编程的真正内涵. 这个例子包括如下几个类 ...
- Spring之IOC/DI(反转控制/依赖注入)_入门Demo
在平时的java应用开发中,我们要实现某一个功能或者说是完成某个业务逻辑时至少需要两个或以上的对象来协作完成,在没有使用Spring的时候,每个对象在需要使用他的合作对象时,自己均要使用像new ob ...
随机推荐
- SSIS 阻塞,半阻塞和全阻塞 (Non-blocking, semi-blocking and Fully-blocking) transformations清单
三种Blocking类型,这里跟数据流的Buff关系很大:■■ non-blocking transformations,每一行直接转换输出,没有等待.■■ partial-blocking tran ...
- 「OC」 基本语法
一.OC简介 在C语言的基础上,增加了一层最小的面向对象语法:完全兼容C语言:可以在OC代码中混入C语言代码,甚至是C++代码:可以使用OC开发Mac OS X平台和iOS平台的应用程序. 二.OC语 ...
- JavaSE学习总结第04天_Java基础语法3
04.01 选择结构switch语句的格式及其解释 switch语句的格式: switch(表达式) { case 值1:语句体1;break; case 值2:语句体2;break; ...
- cookie保存分页参数
<script src="../Public/js/jquery.cookie.js"></script> <script type="te ...
- 让innerHTML方法添加到元素里的js可以被解析执行
<!DOCTYPE html> <html> <head> </head> <body> <div id="test&quo ...
- 安装andriod studio时出现Internal error. Please report to https://code.google.com/p/an
有两种方法的哈 一,在文件中添加 disable.android.first.run=true (我试了这种就好使了哈) 1)进入刚安装的Android Studio目录下的bin目录.找到idea ...
- python爬虫实战1
转载于:http://blog.csdn.net/dongnanyanhai/article/details/5552431 首先推荐一个网站:中医世家,这个网站上有很多关于中医的资料,光是提供的中医 ...
- Python中单引号、双引号和三引号的区别
ython单引号.双引号和三双引号的区别 python字符串通常有单引号('...').双引号("...").三引号("""..."&quo ...
- HDU 4734 F(x) 2013 ACM/ICPC 成都网络赛
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4734 数位DP. 用dp[i][j][k] 表示第i位用j时f(x)=k的时候的个数,然后需要预处理下小 ...
- PDO--PHP Data Objects
PDO的环境配置:开启支持PDO 在php.ini配置文件里开启: extension=php_pdo.dll extension=php_pdo_mysql.dll 在PDO操作中涉及到类:PDO. ...