注解在android中的使用
注解在android程序中的使用
何为注解:
在Java其中,注解又叫做“元数据”,它为我们在源码中加入信息提供了一种形式化的方法。让我们能在以后的某个时间方便的使用这些数据。更确切的说,注解在一定的程度上将数据与元代码进行了绑定,并非将数据保存在外部文件里。当然。这里仅仅介绍Android开发相关的技术。至于注解我会在Java学习总结篇中进行具体的研究和总结。那么。接下来我们一个实例来介绍注解在android开发中的巧妙应用。
实例描写叙述:
在这里。我们使用注解替换掉android中初始化资源对象的findViewById(...)方式,详细例如以下代码所看到的:
我的项目结构:
注解部分:
ContentView.java:
/**
* inject contentview
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ContentView {
int value() default 0;
}
InjectView.java:
/**
* inject view of contentview
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewInject {
int value();
int parentResId() default 0;
}
资源初始化部分:
ViewInjectObj.java:
int parentResId;
Object value;
@Override
public boolean equals(Object obj) {
boolean result;
if(this == obj) {
result = true;
}
if(!(obj instanceof ViewInjectObj)) {
result = false;
}
ViewInjectObj that = (ViewInjectObj) obj;
if(parentResId != that.parentResId) {
result = false;
}
if(null == value) {
return result = (null == that.value);
}
result = value.equals(that.value);
return result;
}
@Override
public int hashCode() {
int result = value.hashCode();
result = 35 * result + parentResId;
return result;
}
@Override
public String toString() {
return "ViewInjectObj [parentResId=" + parentResId + ", value=" + value
+ "]";
}
ViewSelector.java:
/**
* find view id resources
*/
public class ViewSelector {
private Activity currActivity;
private View currView;
public ViewSelector(Activity activity) {
currActivity = activity;
}
public ViewSelector(View view) {
currView = view;
}
public View findViewById(int id) {
return null == currView ? currActivity.findViewById(id) : currView.findViewById(id);
}
public View findViewByInfo(ViewInjectObj info) {
return findViewById((Integer) info.value, info.parentResId);
}
public View findViewById(int id,int pId) {
View pView = null;
if(0 < pId) {
pView = findViewById(pId);
}
View currView = null;
if(null != pView) {
currView = pView.findViewById(id);
} else {
currView = findViewById(id);
}
return currView;
}
}
映射方法部分:
InjectConfig.java:
/**
* inject view methods
*/
public class InjectConfig {
static final String TAG = "InjectConfig";
public InjectConfig() {
}
// inject contentview
public void injectContentView(Object obj,Class<?
> objClass) {
ContentView contentView = objClass.getAnnotation(ContentView.class);
if(null != contentView) {
try {
Method method = objClass.getMethod("setContentView", int.class);
method.invoke(obj, contentView.value());
} catch(Throwable tr) {
Log.e(TAG, tr.getMessage(), tr);
}
}
}
// inject view
public void injectView(Object obj,ViewSelector viewSelector,Class<?> objClass) {
Field[] fields = objClass.getDeclaredFields();
if(null != fields && 0 < fields.length) {
for(Field field : fields) {
ViewInject viewInject = field.getAnnotation(ViewInject.class);
if(null != viewInject) {
try {
View view = viewSelector.findViewById(viewInject.value(), viewInject.parentResId());
if(null != view) {
field.setAccessible(true);
field.set(obj, view);
}
} catch(Throwable tr) {
Log.e(TAG, tr.getMessage(), tr);
}
}
}
}
}
}
调用工具部分:
ViewUtilSvc.java:
public class ViewUtilSvc {
static InjectConfig config = null;
public static void inject(Activity activity) {
inject(activity,new ViewSelector(activity));
}
public static void inject(View view) {
inject(view,new ViewSelector(view));
}
public static void inject(Object obj, View view) {
inject(obj, new ViewSelector(view));
}
static void inject(Object obj,ViewSelector viewSelector) {
if(null == config) {
config = new InjectConfig();
}
Class<?> objClass = obj.getClass();
config.injectContentView(obj, objClass);
config.injectView(obj, viewSelector, objClass);
}
}
前台显示部分:
MainActivity.java:
@ContentView(R.layout.activity_main)
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
ViewUtilSvc.inject(this);
if (savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
public static class PlaceholderFragment extends Fragment {
@ViewInject(R.id.tvHelloWorld)
TextView tvHelloWorld;
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,false);
ViewUtilSvc.inject(this,rootView);
String hello = getResources().getString(R.string.text_helloworld_tv);
tvHelloWorld.setText(hello);
return rootView;
}
}
}
正如上面代码所看到的,我们使用了注解在代码中动态的加入了数据。然后借助反射机制来获得注解的数据;
使用了@ContentView(...) 替代了原生的setContentView(...)部分。使用了ViewUtilSvc.inject(...)进行相应的注射就可以。另外,这种做的目的就是为了简化对象视图的初始化工作。详细的执行效果图例如以下所看到的:
好了,到这里我们的TextView上的hello world最终显示出来了。假设有不论什么问题的话,请在评论中进行发问讨论。
/**
* 技术交流QQ群
*/
注解在android中的使用的更多相关文章
- Android中通过注解代替findViewById方法
转自:http://www.2cto.com/kf/201405/302998.html 这篇文章主要讲解注解实现findViewById的功能,首先我们来熟悉一下在java中怎么定义一个注解和解析一 ...
- 在Android中使用枚举注解而不是枚举
Enums often require more than twice as much memory as static constants. You should strictly avoid us ...
- android 中的一些资源注解,让编译器帮你检查代码
android 中的一些资源注解,让编译器帮你检查代码 写方便的时候可以用注解来声明一些参数,以明确的指示参数的类型,让代码更安全.我们看到,在android源代码里大量使用了注解.我整理了一些注解如 ...
- Android中的自定义注解(反射实现-运行时注解)
预备知识: Java注解基础 Java反射原理 Java动态代理 一.布局文件的注解 我们在Android开发的时候,总是会写到setContentView方法,为了避免每次都写重复的代码,我们需要使 ...
- 理解Android中的注解与反射
反射 Java反射(Reflection)定义 Java反射机制是指在运行状态中 对于任意一个类,都能知道这个类的所有属性和方法:对于任何一个对象,都能够调用它的任何一个方法和属性: 这样动态获取新的 ...
- Android中使用ViewPager实现屏幕页面切换和页面切换效果
之前关于如何实现屏幕页面切换,写过一篇博文<Android中使用ViewFlipper实现屏幕切换>,相比ViewFlipper,ViewPager更适用复杂的视图切换,而且Viewpag ...
- Android中Retrifit使用总结
Android中网络请求框架Retrofit的使用注意事项 1.Retrofit是基于OkHttp网络请求框架的二次封装而已,懂Okhttp的小伙伴,那么Retrofit也就基本都会. 2.Retro ...
- Android中的Touch事件
Android中的Touch事件处理 主要内容 Activity或View类的onTouchEvent()回调函数会接收到touch事件. 一个完整的手势是从ACTION_DOWN开始,到ACTION ...
- Android 进阶 Android 中的 IOC 框架 【ViewInject】 (下)
上一篇博客我们已经带大家简单的吹了一下IoC,实现了Activity中View的布局以及控件的注入,如果你不了解,请参考:Android 进阶 教你打造 Android 中的 IOC 框架 [View ...
随机推荐
- 自定制emoji替换系统的emoji键盘
一.关于emoji表情 随着iOS系统版本的升级,对原生emoji表情的支持也越来越丰富.emoji表情是unicode码中为表情符号设计的一组编码,当然,还有独立于unicode的另一套编码SBUn ...
- STM32使用串口1配合DMA接收不定长数据,减轻CPU载荷
STM32使用串口1配合DMA接收不定长数据,减轻CPU载荷 http://www.openedv.com/thread-63849-1-1.html 实现思路:采 用STM32F103的串口1,并配 ...
- javascript:void(0)的作用示例
在做页面时,如果想做一个链接点击后不做任何事情,或者响应点击而完成其他事情,可以设置其属性 href = "#",但是,这样会有一个问题,就是当页面有滚动条时,点击后会返回到页面顶 ...
- Android:设置背景图和标题
在MainActivity.onCreate(Bundle savedInstanceState){}设置背景图和标题. setTitle("wyl的diary");//标题,即左 ...
- 清华申请退学博士作品:完全用Linux工作,凸Windows
清华申请退学博士作品:完全用Linux工作 按尽管我们已经不习惯看长篇大论, 但我还是要说, 这是一篇值得你从头读到尾的长篇文章. 2005年9月22日,清华在读博士生王垠在水木社区BLOG上发表了& ...
- Search Insert Position--寻找插入点Given a sorted array and a target value, return the index if the target
问题:链接 Given a sorted array and a target value, return the index if the target is found. If not, retu ...
- Axis2(8):异步调用WebService
在前面几篇文章中都是使用同步方式来调用WebService.也就是说,如果被调用的WebService方法长时间不返回,客户端将一直被阻塞,直到该方法返回为止.使用同步方法来调用WebService虽 ...
- 采用sharedPreference保存数据
1.sharedPreference保存数据 package com.example.login.service; import java.io.BufferedReader; import java ...
- Python中打印列表的序号和内容
==>the start 最近作业里要用到遍历打印出列表中的序号和内容,我刚开始用了个很笨的方法来写,后来老师说可以使用enumerate()函数,所以我就特意研究了下. 先看我之前用的笨方法: ...
- Android 判断当前线程是否为主线程
public static boolean isInMainThread() { return Looper.myLooper() == Looper.getMainLooper(); }