本篇介绍功能代码复用架构中的细节
- 注解
- EVENT_TYPE 指明当前Action触发的事件类型,我默认是TYPE_WINDOW_STATE_CHANGED,它的使用频率比较高,如果有其他的TYPE_VIEW_CLICK或者TYPE_CONTENT_CHANGE,可以自己定义。
- EVENT_CLASS 引起当前事件的节点类名,如果是适配微信不同版本的话,可能一个页面的类名不一样,就会用到下面的注解。
- EVENT_CLASSES 同时指出多个类名来执行这个Action,使用不同版本微信适配。
- TASK_IDS 这里的作用是在ActionService中标记这个Action是属于哪个任务id的,作用就是在AccessibilityService-onAccessibilityEvent(event)中去区分不同的功能任务。
- RUN 作用就是在ActionService中知名Action的类名。
…还有一些自己定义的辅助注解。
- 具体的执行action的时候在先获取当前taskId的所有Action:
try {
List<Method> methods = mTaskMethods.get(taskId);
if (methods == null) {
List<Method> taskMethods = new ArrayList<>();
for (Method method : ActionService.class.getDeclaredMethods()) {
int[] task_ids = method.getAnnotation(TASK_IDS.class).value();
for (int task_id : task_ids) {
if (task_id == taskId) {
taskMethods.add(method);
break;
}
}
}
mTaskMethods.put(taskId, methods = taskMethods);
}
for (Method method : methods) {
method.invoke(H.getInstance().createService(), event);
}
//update lastest oprate timestrap
mUpdateTime = System.currentTimeMillis();
} catch (Exception e) {
e.printStackTrace();
}
- 在代理中执行的时候,去取出每个Action上面的eventType和className:
ActionAssertEntity actionAssertEntity = mActions.get(method);
if (actionAssertEntity == null) {
int type = -1;
String className = null;
String[] classNames = null;
Annotation[] annotations = method.getAnnotations();
if (annotations != null) {
Class<? extends Action> run = method.getAnnotation(RUN.class).value();
Annotation[] annotations1 = run.getAnnotations();
if (annotations1 != null) {
for (Annotation annotation : annotations1) {
if (annotation instanceof EVENT_TYPE) {
type = ((EVENT_TYPE) annotation).value();
} else if (annotation instanceof EVENT_CLASS) {
className = ((EVENT_CLASS) annotation).value();
} else if (annotation instanceof EVENT_CLASSES) {
classNames = ((EVENT_CLASSES) annotation).value();
}
}
}
if (type < 0) {
throw new IllegalArgumentException("类 " + run.getName() + "必须指定一个触发事件的类型 EVENT_TYPE 来过滤触发的事件");
}
if (TextUtils.isEmpty(className) && (classNames == null || classNames.length == 0)) {
throw new IllegalArgumentException("类 " + run.getName() + "必须指定一个类名 EVENT_CLASS 来过滤触发的事件");
}
mActions.put(method, actionAssertEntity = new ActionAssertEntity().eventType(type).className(className).classNames(classNames).action(run.newInstance()));
} else {
throw new IllegalArgumentException("you should identify the required annotations!");
}
}
这样就实现了retrofit2式的代理架构。学以致用,嘿嘿。