最近考试周没什么时间写,回归正题。前面的一次简单的讲了关于注解的的基础部分,这一次分析xutils注解封装的源码(奉上github源码)。
补充下:xUtils 2.x对Android 6.0兼容不是很好, 请尽快升级至xUtils3。(如网络部分:android 6.0(api 23) SDK,不再提供org.apache.http.*(只保留几个类))
(1) 注解模块目录结构
(2) 分析源代码
1.元注解--annoation文件夹下三个注解
ContentView:对于activity设置布局文件
/* * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.xutils.view.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE)//使用范围--类,接口,枚举,Annotation类型 @Retention(RetentionPolicy.RUNTIME)//有效范围--运行时有效 public @interface ContentView { int value();//布局资源 }
Event:
package org.xutils.view.annotation; import android.view.View; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 事件注解. * 被注解的方法必须具备一下形式: * 1. private 修饰 * 2. 返回值类型没有要求 * 3. 方法名以Click或Event结尾, 否则可能被混淆编译时删除. (方法签名形式为void *(android.view.View)也可以) * 4. 参数签名和type的接口要求的参数签名一致. * Author: wyouflf * Date: 13-9-9 * Time: 下午12:43 */ @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 ""; }
ViewInject:绑定控件id
/* * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.xutils.view.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();//绑定控件id /* parent view id */ int parentId() default 0;//绑定控件父布局id 默认是取0 }
2.View文件夹下4个类
ViewInfo--1.控件注解生成ViewInfo;
2.对于散列集合包括HashSet、HashMap以及HashTable通过先比较hashcode相等再比较equals来提高效率
package org.xutils.view; /** * 比较两个ViewInfo是否相等 * Author: wyouflf * Date: 13-12-5 * Time: 下午11:25 */ /*package*/ final class ViewInfo { public Object value; public int parentId; @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof ViewInfo)) return false; ViewInfo that = (ViewInfo) o; if (parentId != that.parentId) return false; if (value == null) return (null == that.value); return value.equals(that.value); } @Override public int hashCode() { int result = value.hashCode(); result = 31 * result + parentId; return result; } }
ViewInjector--定义注解绑定的接口不再详细贴了
ViewInjectorImpl(重点)--实现注解绑定接口的实现类(包括控件绑定,布局资源绑定,控件的事件绑定)
使用单例模式双重检查锁定创建ViewInjectorImpl对象并保证线程安全
简单的做了ViewInjectorImpl类的分析:
错误之处还请指出-_-。。。