banner
NEWS LETTER

IOC注解框架

Scroll down

写在前面

打造自己的简单IOC注解框架

1.创建annotation类

View

1
2
3
4
5
6
7
//代表Annotation的位置, FIELD属性 TYPE类上   CONSTRUCTOR构造函数上
@Target(ElementType.FIELD)
//代表什么时候生效 CLASS编译时 RUNTIME运行时 SOURCE源码时
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewById {
int value();
}

点击监听

1
2
3
4
5
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OnClick {
int[] value();
}

网络状态判断

1
2
3
4
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckNet {
}

2.创建View的findViewById的辅助类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ViewFinder {
private Activity mActivity;
private View mView;

public ViewFinder(Activity activity) {
this.mActivity = activity;
}

public ViewFinder(View view) {
this.mView = view;
}

public View findViewById(int viewId) {
return mActivity != null ? mActivity.findViewById(viewId) : mView.findViewById(viewId);
}
}

3.创建工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
public class ViewUtils {
public static void inject(Activity activity) {
inject(new ViewFinder(activity), activity);
}

public static void inject(View view) {
inject(new ViewFinder(view), view);
}

public static void inject(View view, Object object) {
inject(new ViewFinder(view), object);
}
//兼容 上面三个方法,object -> 反射需要执行的类
private static void inject(ViewFinder finder, Object object) {
injectField(finder, object);
injectEvent(finder, object);
}


// 注入属性
private static void injectField(ViewFinder finder, Object object) {
//1.获取类里面的所有属性
Class<?> clazz = object.getClass();
// 获取所有属性包括私有和共有
Field[] fields = clazz.getDeclaredFields();
//2.获取ViewById找到view
for (Field field : fields) {
ViewById viewById = field.getAnnotation(ViewById.class);
if (viewById != null) {
//获取注解里的id值->R.id.xx
int viewId = viewById.value();
//3.findViewById找到view
View view = finder.findViewById(viewId);
if (view != null) {
//能够注入所有修饰符private public
field.setAccessible(true);
try {
//4.动态注入扎到view
field.set(object, view);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}

private static void injectEvent(ViewFinder finder, Object object) {
Class<?> clazz = object.getClass();
Method[] methods = clazz.getDeclaredMethods();

for (Method method : methods) {
OnClick onClick = method.getAnnotation(OnClick.class);
if (onClick != null) {
int[] viewIds = onClick.value();
for (int viewId : viewIds) {
View view = finder.findViewById(viewId);
boolean isCheckNet = method.getAnnotation(CheckNet.class) != null;

if (view != null) {
view.setOnClickListener(new DeclaredOnClickListener(method, object, isCheckNet));
}
}
}
}
}

private static class DeclaredOnClickListener implements View.OnClickListener {
private final Object mObject;
private final Method mMethod;
private final boolean mIsCheckNet;

public DeclaredOnClickListener(Method method, Object object, boolean isCheckNet) {
this.mMethod = method;
this.mObject = object;
this.mIsCheckNet = isCheckNet;
}

@Override
public void onClick(View v) {
if (mIsCheckNet) {
if (!networkAvailable(v.getContext())) {
Toast.makeText(v.getContext(), "网络不可用", Toast.LENGTH_SHORT).show();
return;
}
}
try {
mMethod.setAccessible(true);
mMethod.invoke(mObject, v);
} catch (Exception e) {
e.printStackTrace();
try {
mMethod.setAccessible(true);
mMethod.invoke(mObject, null);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}

private static boolean networkAvailable(Context context) {
try {
ConnectivityManager connectivityManager = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetWorkInfo = connectivityManager.getActiveNetworkInfo();
if (activeNetWorkInfo != null && activeNetWorkInfo.isConnected()) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}

使用方法

1
2
3
4
5
6
7
8
9
@ViewById(R.id.test_tv)
private TextView textView;


@CheckNet
@OnClick(R.id.test_tv)
private void onClick(View view) {
Toast.makeText(this, "click", Toast.LENGTH_SHORT).show();
}
其他文章
目录导航 置顶
  1. 1. 写在前面
  • 1.创建annotation类
    1. 1. View
    2. 2. 点击监听
    3. 3. 网络状态判断
  • 2.创建View的findViewById的辅助类
  • 3.创建工具类
  • 使用方法
  • 请输入关键词进行搜索