xUtils -- view模块分析
来源:互联网 发布:vue.js v bind的用法 编辑:程序博客网 时间:2024/05/22 00:18
简介
xUtils是Android的工具库,其中包含有View、Bitmap、Db、Http四个模块。
本篇主要争对xUtils的2.6.14版本和xUtils3版本的View模块做个分析。
View模块主要提供功能有View布局的绑定,事件的绑定。而在xUtils2.6.14中还提供资源绑定等功能。
使用
@ContentView(R.layout.activity_main)public class MainActivity extends Activity { @ViewInject(R.id.btn) Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); x.view().inject(this); } @Event(value = R.id.btn, type = View.OnLongClickListener.class) private boolean onBtnClick(View view) { Toast.makeText(MainActivity.this, "onBtnClick", Toast.LENGTH_SHORT).show(); return true; }}
简要分析
主要通过注解,反射,动态代理的技术。
在定义View时添加注解,确定所要注入的id等信息,并在Activity启动的onCreate方法执行注入x.view().inject(this);
,而对于事件的绑定则还需要通过动态代理来实现。
图片很好概括了这个过程,图片来自于xUtils 源码解析
关于注解的文章:
Java注解实践
公共技术点之 Java 注解 Annotation
关于反射的文章:
公共技术点之 Java反射 Reflection
关于动态代理的文章:
公共技术点之 Java 动态代理
Java 动态代理机制分析及扩展
xUtils2.6.14和xUtils3分析
两者都支持注解ContentView、View、Event。
但是2.6.14版本支持注解资源,还有preference,这些功能在xUtils3被移除掉。
xUtils2.6.14和xUtils3的View部分变化主要在Event部分,对比两个版本View模块注解,可以发现2.6.14版本的事件注解类型多,而且扩展性不高,
先看下xUtils2.6.14事件注解
// xUtils2.6.14@Target(ElementType.ANNOTATION_TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface EventBase { Class<?> listenerType(); String listenerSetter(); String methodName();}// onClick方法注解 其他注解类似@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@EventBase( listenerType = View.OnClickListener.class, listenerSetter = "setOnClickListener", methodName = "onClick")public @interface OnClick { int[] value(); int[] parentId() default 0;}
再看下xUtils3的事件注解:
@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Event { /** * 控件的id集合, id小于1时不执行ui事件绑定. * * @return */ int[] value(); /** * 控件的parent控件的id集合, 组合为(value[i], parentId[i] or 0). * * @return */ int[] parentId() default 0; /** * 事件的listener, 默认为点击事件. * * @return */ Class<?> type() default View.OnClickListener.class; /** * 事件的setter方法名, 默认为set+type#simpleName. * * @return */ String setter() default ""; /** * 如果type的接口类型提供多个方法, 需要使用此参数指定方法名. * * @return */ String method() default "";}
xUtils3通过使用一个注解表示事件。
看下主要函数:
private static void injectObject(Object handler, ViewFinder finder) { Class<?> handlerType = handler.getClass(); // inject ContentView ContentView contentView = handlerType.getAnnotation(ContentView.class); // ... Method setContentViewMethod = handlerType.getMethod("setContentView", int.class); setContentViewMethod.invoke(handler, contentView.value()); // ... // inject view Field[] fields = handlerType.getDeclaredFields(); if (fields != null && fields.length > 0) { for (Field field : fields) { ViewInject viewInject = field.getAnnotation(ViewInject.class); if (viewInject != null) { try { View view = finder.findViewById(viewInject.value(), viewInject.parentId()); if (view != null) { field.setAccessible(true); field.set(handler, view); } } catch (Throwable e) { LogUtils.e(e.getMessage(), e); } } else { // inject resourse ResInject resInject = field.getAnnotation(ResInject.class); if (resInject != null) { try { Object res = ResLoader.loadRes( resInject.type(), finder.getContext(), resInject.id()); if (res != null) { field.setAccessible(true); field.set(handler, res); } } catch (Throwable e) { LogUtils.e(e.getMessage(), e); } } else { // inject preference // ... field.set(handler, preference); // ... } } } } // inject event Method[] methods = handlerType.getDeclaredMethods(); if (methods != null && methods.length > 0) { for (Method method : methods) { Annotation[] annotations = method.getDeclaredAnnotations(); if (annotations != null && annotations.length > 0) { for (Annotation annotation : annotations) { Class<?> annType = annotation.annotationType(); if (annType.getAnnotation(EventBase.class) != null) { method.setAccessible(true); try { // ... for (int i = 0; i < len; i++) { ViewInjectInfo info = new ViewInjectInfo(); info.value = Array.get(values, i); info.parentId = parentIdsLen > i ? (Integer) Array.get(parentIds, i) : 0; // 动态代理处理 EventListenerManager.addEventMethod(finder, info, annotation, handler, method); } } catch (Throwable e) { LogUtils.e(e.getMessage(), e); } } } } } } }
而对于这一个过程分析及实现的有
打造IOC框架 上
打造IOC框架 下
总结
本篇博客简单分析xUtils的view注入过程,和对xUtils版本改进后的理解。
View的注入使用了注解和反射等技术,在开发过程中难免会造成资源浪费以及效率低下,但是这一过程涉及到Java的注解和反射以及动态代理等技术,还是非常值得去学习,而不是只会使用。
最后,如哪里不足或者分析错误,非常欢迎指正,谢谢。
- xUtils -- view模块分析
- XUtils的view模块
- android Xutils Http模块分析
- xUtils框架之HttpUtils模块分析
- Android开源项目xUtils HttpUtils模块分析
- Android开源项目xUtils HttpUtils模块分析
- XUtils 源码分析(一)--网络操作模块
- XUtils 源码分析(二)--图片缓存模块
- XUtils 源码分析(三)--数据库操作模块
- xutils网络模块bug
- xUtils使用-----db模块
- XUtils的bitmap模块
- xutils的http模块
- xUtils之view注入--Android
- Xutils之View相关问题
- XUtils BitmapUtils 源码分析
- xutils 四大模块的使用
- xUtils异步HTTP源码分析
- mysql-5.6.27-winx64 achieve 配置
- 习题3-1 得分 UVa1585
- HDOJ 3364 Lanterns (高斯消元)
- DIV+IFrame实现页面弹出窗口
- hdu 2131 Probability
- xUtils -- view模块分析
- iOS开发工具介绍之一 backlight
- Lua数据结构 — TString(二)
- nyoj 127 星际之门(一)
- 看博客和评博客意义何在?
- 《高性能 MySQL》读书笔记
- 数据库编程——JDBC 配置
- Delphi中始终用WebBrowser打开网页
- Lua数据结构 — 闭包(四)