Android注解IOC框架【ViewInject】(一)

你还在为setContentView()烦恼吗?

或者说,你还在为findViewById()烦恼吗?

如果是,请往下看...

IOC我们都知道,控制反转(Inversion of Control) 就是项目分层 具体理论概述个人去查资料...

之前听‘前辈’提过注解,但那会儿不知道是神马,只知道听起来很神奇,因为‘前辈说’:不用去写什么setContentView和findViewById之类的代码了,尤其是findViewById,想必大家都是深有体会,如果一个界面有十个view,就会有十行的findViewById...现在,有了注解之后,不需要了 一行搞定!

首先,我们需要两个注解文件:

ContentView.java:

package com.yx.viewinject_demo.ui;

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

/***
 *
 * 此类描述的是: ContentView用于在类上使用,主要用于标明该Activity需要使用的布局文件
 *
 * @author: CS YX
 * @version:1.0
 * @date:2014-10-14 上午9:55:03
 */
@Target(ElementType.TYPE)
/*
 * @Target表示该注解可以用于什么地方,可能的类型TYPE(类),FIELD(成员变量)
 * 可能的类型:TYPE、FIELD、METHOD、PARAMETER、CONSTRUCTOR
 * 、LOCAL_VARIABLE、ANNOTATION_TYPE、PACKAGE
 */
@Retention(RetentionPolicy.RUNTIME)
/* @Retention表示:表示需要在什么级别保存该注解信息;我们这里设置为运行时。 可能的类型:SOURCE、CLASS、RUNTIME */
public @interface ContentView {
	int value();
}

这个注解文件是用于注入布局的,放在Activity类前面,标明该Activity引用的布局:

@ContentView(value = R.layout.activity_main)
public class MainActivity extends Activity 

然后是第二个注解文件:

ViewInject.java

package com.yx.viewinject_demo.ui;

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

/***
 *
 * 此类描述的是: 在成员变量上使用,用于指定View的Id
 *
 * @author: CS YX
 * @version:1.0
 * @date:2014-10-14 上午9:57:21
 */
@Target(ElementType.FIELD)
/*
 * @Target表示该注解可以用于什么地方,可能的类型TYPE(类),FIELD(成员变量)
 * 可能的类型:TYPE、FIELD、METHOD、PARAMETER、CONSTRUCTOR
 * 、LOCAL_VARIABLE、ANNOTATION_TYPE、PACKAGE
 */
@Retention(RetentionPolicy.RUNTIME)
/* @Retention表示:表示需要在什么级别保存该注解信息;我们这里设置为运行时。 可能的类型:SOURCE、CLASS、RUNTIME */
public @interface ViewInject {
	int value();
}

这个注解文件是用于注入View控件,用于指定View的Id

	@ViewInject(R.id.bt1)
	private Button bt1;
	@ViewInject(R.id.bt2)
	private Button bt2;

现在,我们需要定义一个ViewInject帮助类,这是核心类。

ViewInjectUtils.java:

package com.yx.viewinject_demo.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import com.yx.viewinject_demo.ui.ContentView;
import com.yx.viewinject_demo.ui.ViewInject;

import android.app.Activity;

/***
 *
 * 此类描述的是: 注解帮助类
 *
 * @author: CS YX
 * @version:1.0
 * @date:2014-10-14 上午10:09:35
 */
public class ViewInjectUtils {
	private static final String METHOD_SET_CONTENTVIEW = "setContentView";
	private static final String METHOD_FIND_VIEW_BY_ID = "findViewById";

	/**
	 *
	 * 此方法描述的是: 注入布局和view控件
	 *
	 * @param activity
	 *            Activity对象
	 */
	public static void inject(Activity activity) {
		// 注入布局文件
		injectContentView(activity);
		// 注入所有View控件
		injectViews(activity);
	}

	/***
	 *
	 * 此方法描述的是: 注入布局文件
	 *
	 * @param activity
	 *            Activity对象
	 */
	private static void injectContentView(Activity activity) {

		Class<? extends Activity> clazz = activity.getClass();
		// 查询类上是否有注解
		ContentView contentView = clazz.getAnnotation(ContentView.class);
		if (contentView != null) {// 存在,不为空
			// 注解的ID
			int contentViewLayoutId = contentView.value();
			try {
				// 获得Method对象
				Method method = clazz.getMethod(METHOD_SET_CONTENTVIEW,
						int.class);
				// 设置属性可访问(私有)
				method.setAccessible(true);
				method.invoke(activity, contentViewLayoutId);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 *
	 * 此方法描述的是: 注入所有控件
	 *
	 * @param activity
	 *            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) {
				// 获得view的Id
				int viewInjectId = viewInject.value();
				if (viewInjectId != -1) {
					Method method;
					try {
						// 获得Method对象
						method = clazz.getMethod(METHOD_FIND_VIEW_BY_ID,
								int.class);
						Object resView = method.invoke(activity, viewInjectId);
						// 设置属性可访问(私有)
						field.setAccessible(true);
						field.set(activity, resView);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

				}

			}

		}

	}

}

代码已经基本写完了,只剩最后一个MainActivity:

MainActivity.java:

package com.yx.viewinject_demo.ui;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.yx.viewinject_demo.R;
import com.yx.viewinject_demo.utils.ToastUtils;
import com.yx.viewinject_demo.utils.ViewInjectUtils;

/**
 *
 * 此类描述的是: 应用主界面
 *
 * @author: CS YX
 * @version:1.0
 * @date:2014-10-21 上午10:08:31
 */
@ContentView(value = R.layout.activity_main)
public class MainActivity extends Activity implements OnClickListener {
	@ViewInject(R.id.bt1)
	private Button bt1;
	@ViewInject(R.id.bt2)
	private Button bt2;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 注入布局和控件
		ViewInjectUtils.inject(MainActivity.this);
		//设置onClick事件
		bt1.setOnClickListener(MainActivity.this);
		bt2.setOnClickListener(MainActivity.this);

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.bt1:
			ToastUtils.showShort(this, "Hi,this is bt1...");
			break;
		case R.id.bt2:
			ToastUtils.showShort(this, "Hello,this is bt2...");
			break;

		default:
			break;
		}
	}

}

代码写完了,效果图如下:

demo地址 点击下载demo

感谢:http://blog.csdn.net/lmj623565791/article/details/39269193





时间: 2024-10-15 08:01:04

Android注解IOC框架【ViewInject】(一)的相关文章

来,咱们自己写一个Android的IOC框架!

到目前位置,afinal开发框架也是用了好几个月了,还记得第一次使用注释完成控件的初始化和事件绑定的时候,当时的心情是多么的兴奋- -代码竟然可以这样写!然后随着不断的学习,也慢慢的对IOC框架和注解反射等东西有了一点简单的了解,之前的一篇文章简单的介绍了一下Java的反射机制,今天的文章,就完成一个简单的,基于IOC的小Demo,让大家慢慢的对IOC有一点简单的了解. 首先,什么是IOC呢? 控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来

【Android开发经验】来,咱们自己写一个Android的IOC框架!

到眼下位置.afinal开发框架也是用了好几个月了,还记得第一次使用凝视完毕控件的初始化和事件绑定的时候,当时的心情是多么的兴奋- -代码居然能够这样写!然后随着不断的学习,也慢慢的对IOC框架和注解反射等东西有了一点简单的了解.之前的一篇文章简单的介绍了一下Java的反射机制.今天的文章.就完毕一个简单的,基于IOC的小Demo.让大家慢慢的对IOC有一点简单的了解. 首先.什么是IOC呢? 控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来

Android 进阶 教你打造 Android 中的 IOC 框架 【ViewInject】

1.概述 首先我们来吹吹牛,什么叫IoC,控制反转(Inversion of Control,英文缩写为IoC),什么意思呢? 就是你一个类里面需要用到很多个成员变量,传统的写法,你要用这些成员变量,那么你就new 出来用呗~~ IoC的原则是:NO,我们不要new,这样耦合度太高:你配置个xml文件,里面标明哪个类,里面用了哪些成员变量,等待加载这个类的时候,我帮你注入(new)进去: 这样做有什么好处呢? 回 答这个问题,刚好可以回答另一个问题,很多人问,项目分层开发是吧,分为控制层.业务层

Android 进阶 教你打造 Android 中的 IOC 框架 【ViewInject】 (上)

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39269193,本文出自:[张鸿洋的博客] 1.概述 首先我们来吹吹牛,什么叫IoC,控制反转(Inversion of Control,英文缩写为IoC),什么意思呢? 就是你一个类里面需要用到很多个成员变量,传统的写法,你要用这些成员变量,那么你就new 出来用呗~~ IoC的原则是:NO,我们不要new,这样耦合度太高:你配置个xml文件,里面标明哪个类,里面用了哪些成员变

Android Afinal框架学习(二) FinalActivity 一个IOC框架

框架地址:https://github.com/yangfuhai/afinal 对应的源码: net.tsz.afinal.annotation.view.* FinalActivity FinalActivity是一个基础类,结合注解实现了,依赖注入(view的资源id,常用的监听器), 利用set方式注入 完全注解方式就可以进行UI绑定和事件绑定,无需findViewById和set event Listener 这个过程:initInjectedView>findViewById.set

Android 打造编译时注解解析框架 这只是一个开始

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/43452969 ,本文出自:[张鸿洋的博客] 1.概述 记得很久以前,写过几篇博客,容我列举一下: Android 进阶 教你打造 Android 中的 IOC 框架 [ViewInject] (上) Android 进阶 教你打造 Android 中的 IOC 框架 [ViewInject] (下) Android 框架炼成 教你如何写组件间通信框架EventBus 大家可以关

Android注解使用之通过annotationProcessor注解生成代码实现自己的ButterKnife框架

前言: Annotation注解在Android的开发中的使用越来越普遍,例如EventBus.ButterKnife.Dagger2等,之前使用注解的时候需要利用反射机制势必影响到运行效率及性能,直到后来android-apt的出现通过注解根据反射机制动态编译生成代码的方式来解决在运行时不再使用发射机制,不过随着android-apt的退出不再维护,我们今天利用Android studio的官方插件annotationProcessor来实现一下自己的ButterKnife UI注解框架. 需

Android自助餐之控件注解IOC

Android自助餐之控件注解IOC Android自助餐之控件注解IOC 支持的事件 使用步骤 支持的事件: onCheckedChanged() onClick() onEditorAction() onFocusChange() onItemClick() onItemLongClick() onItemSelected() onLongClick() onPageChange() onTextChanged() onTouch() 使用步骤 首先在build.gradle中添加 comp

Android开发之注解式框架ButterKnife在ADT中的设置

使用注解式框架ButterKnife的时候,导入到ADT中,结果项目中注解的view无效,如点击button等无任何的反应. 然后在ButterKnife的官网查看到解决办法:http://jakewharton.github.io/butterknife/ide-eclipse.html 1.因为使用的是ADT,需要在工程的设置中的Java Compiler → Annotation Processing and check "Enable project specific settings&