注解在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群:179914858

*/

注解在android中的使用

时间: 2024-10-12 09:23:57

注解在android中的使用的相关文章

Android中ViewMapping注解

1.Java.lang包中常用的注解有@Override,@Deprected(已经废弃),@SupressWarning(屏蔽掉一些警告.)我们可以自定义注解. 2.Java注解之@Retention,@Documented,@Inherited. Retention注解,保留注解说明,这种类型的猪儿会被保留到哪个阶段,有三个值:RetentionPolicy.SOURCE(只有源码级别保留,编译时被忽略),RetentionPolicy.CLASS(class文件中保留,Jvm被忽略),Re

Android中通过注解代替findViewById方法

尊重原创 http://write.blog.csdn.net/postedit/26507351 这篇文章主要讲解注解实现findViewById的功能,首先我们来熟悉一下在java中怎么定义一个注解和解析一个注解 注解的概念是在jdk5.0中提出来的,在java.lang的包中已经定义了三个注解:Override,Deprecated,SuppressWarnings Override相信大家非常熟悉,就是表明这个方法是改写了父类的方法 Deprecated表示在新版本的 jdk中已经不建议

理解Android中的注解与反射

前言 最近一段时间在研究EventBus和Retrofit 的过程中,都遇到了注解这个概念.由于在学习Java的时候对这方面没有深入了解过,所以看起相关的代码来,总会有点不知其所以然,这里就注解和反射的使用做一下总结. 这里我们先从反射说起,了解了反射的意义及用法后,我们在看看注解的使用,最后叙述一下在Android开发中是怎样结合使用注解与反射. 反射 Java反射(Reflection)定义 Java反射机制是指在运行状态中 对于任意一个类,都能知道这个类的所有属性和方法: 对于任何一个对象

android 中的一些资源注解,让编译器帮你检查代码

android 中的一些资源注解,让编译器帮你检查代码 写方便的时候可以用注解来声明一些参数,以明确的指示参数的类型,让代码更安全.我们看到,在android源代码里大量使用了注解.我整理了一些注解如下: @NonNull  告诉编译器,这个参数是非空的,编译器会帮你做出检查. 示例: @NonNull public static Snackbar make(@NonNull View view, @StringRes int resId, @Duration int duration) {  

【转载】如何在Android中避免创建不必要的对象

在编程开发中,内存的占用是我们经常要面对的现实,通常的内存调优的方向就是尽量减少内存的占用.这其中避免创建不必要的对象是一项重要的方面. Android设备不像PC那样有着足够大的内存,而且单个App占用的内存实际上是比较小的.所以避免创建不必要的对象对于Android开发尤为重要. 本文会介绍一些常见的避免创建对象的场景和方法,其中有些属于微优化,有的属于编码技巧,当然也有确实能够起到显著效果的方法. 使用单例 单例是我们常用的设计模式,使用这种模式,我们可以只提供一个对象供全局调用.因此单例

Android中Xml工具类的封装

Android中经常使用到操作XML,其中有一对XmlSerializer和XmlPullParser封装的很好,可是操作起来很复杂,虽然不难,但是感觉做了一点小事却写了一大堆的代码.有点烦,因此封装一下. 其思路为:根据传入的数据,获取字节码后进行反射解析,然后在存储.思路很简单,此demo只写了一个基本的List<T>类型的,其它类型道理与此大同小异,就当这个是抛砖引玉了. 对于一些Model可能有些字段是不需要序列化的,这里可以使用注解来操作 /** * XML操作工具类 * @auth

Android中使用ViewPager实现屏幕页面切换和页面轮播效果

之前关于如何实现屏幕页面切换,写过一篇博文<Android中使用ViewFlipper实现屏幕切换>,相比ViewFlipper,ViewPager更适用复杂的视图切换,而且Viewpager有自己的adapter,这也让其适应复杂对象,实现数据的动态加载. ViewPager是谷歌官方给我们提供的一个兼容低版本安卓设备的软件包,里面包囊了只有在安卓3.0以上可以使用的api.而viewpager就是其中之一,利用它,我们可以做很多事情,从最简单的导航,到页面菜单等等. 下面我们就展示下Vie

Android中AsyncTask使用具体解释

在Android中我们能够通过Thread+Handler实现多线程通信.一种经典的使用场景是:在新线程中进行耗时操作.当任务完毕后通过Handler向主线程发送Message.这样主线程的Handler在收到该Message之后就能够进行更新UI的操作.上述场景中须要分别在Thread和Handler中编写代码逻辑,为了使得代码更加统一,我们能够使用AsyncTask类. AsyncTask是Android提供的一个助手类,它对Thread和Handler进行了封装,方便我们使用. Andro

Android中WebView的JavaScript代码和本地代码交互的三种方式

一.Android中WebView的漏洞分析 最近在开发过程中遇到一个问题,就是WebView使用的时候,还是需要解决之前系统(4.2之前)导致的一个漏洞,虽然现在这个系统版本用户很少了,但是也不能忽视,关于这个漏洞,这里就不多做解释了,可能有的同学早就了解了,本来想写一篇文章详细介绍一下,但是网上的知识太多了,而且都很详细,就没弄了,这里大致简单明了的说几句: 第一.漏洞产生的原因 这个漏洞导致的原因主要是因为Android中WebView中的JS访问本地方法的方式存在缺陷,我们做过交互的都知