一 使用注解在编译时将路径的数据封装在RouteMeta类中 并且在实现IRouteGroup类中 添加到参数atlas map中
特殊的类
@AutoService(Processor.class) 主要的作用是注解 processor类,并对其生成 META-INF 的配置信息。
javapoet 帮助生成代码
IRouteGroup 生成的类实现了此接口 便于在运行时使用封装的数据
二 初始化Arouter时 通过反射调用自动生成的类(继承自IRouteGroup)的loadInto 方法把路径和对应的类保存到缓存中
((IRouteRoot) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.groupsIndex);
className : 自动生成的类的路径
Warehouse.groupsIndex : 缓存的map
三 Arouter跳转
通过path路径去缓存中找到对应的类做跳转
*为什么要分成两个依赖module*
因为annotationProcessor project(':lib') 只参与编译
在android中写注解一般分两个module,一个是专门存放的注解类比如叫apt-lib,一个是注解解释类比如叫apt-process,后一个依赖前一个。apt-lib提供api要打入apk的,apt-process只参与编译。
apt-process中的build.gradle
compile project(':apt-lib')
app中的build.gradle
compile project(":apt-lib")
annotationProcessor project(':apt-process')
一 创建
创建注解 java module:arouter_annotaion 创建route注解 RouteMeta封装类
创建编译时 java module : aroter_compiler 创建AutowiredProcessor类
需要引入
implementation ‘com.google.auto.service:auto-service:1.0-rc2’ //@AutoService(Processor.class) 调用
implementation ‘com.squareup:javapoet:1.7.0’ //帮助自动生成java类的依赖
需要依赖 arouter_annotaion module
processor里面主要两个方法
init() 初始化一些方法
process() 解析注解 自动生成java类
创建api调用 android module : arouter_appi 创建出事Arouter类 IRouteGroup接口
需要依赖 arouter_annotaion module
二 使用
在app中引用上面三种module
annotationProcessor project(':aroter_compiler')
implementation project(':arouter_annotaion')
implementation project(':arouter_appi')
在aplication中 初始化
Arouter.getInstance().init(getApplication());
在需要的页面添加路由
@Route(path = "ThreeActivity")
调用 Arouter.getInstance().build("ThreeActivity");
相关类
arouter_annotaion module
package com.example.aroter_compiler;
import com.example.arouter_annotaion.Route;
import com.example.arouter_annotaion.RouteMeta;
import com.google.auto.service.AutoService;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeSpec;
import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import static javax.lang.model.element.Modifier.PUBLIC;
/**
* Created by qf on 2018/7/25
* 描述: AutowiredProcessor
*/
@AutoService(Processor.class)
public class AutowiredProcessor extends AbstractProcessor {
private Filer mFiler;
private Types mTypeUtils;
private Elements mElementUtils;
// System interface
public static final String ACTIVITY = "android.app.Activity";
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
//初始化一些工具类
mTypeUtils = processingEnv.getTypeUtils();
mElementUtils = processingEnv.getElementUtils();
mFiler = processingEnv.getFiler();
}
@Override
public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment) {
System.out.println("ele====activity_");
if (null != roundEnvironment) {
Set extends Element> elementsAnnotatedWith = roundEnvironment.getElementsAnnotatedWith(Route.class);
doElements(elementsAnnotatedWith);
return true;
}
return false;
}
@Override
public Set getSupportedAnnotationTypes() {
Set annotations = new LinkedHashSet<>();
annotations.add(Route.class.getCanonicalName());
return annotations;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
private void doElements(Set extends Element> elementsAnnotatedWith) {
TypeMirror activityMirror = mElementUtils.getTypeElement(ACTIVITY).asType();
//定义参数
ParameterizedTypeName inputMapTypeOfGroup = ParameterizedTypeName.get(
ClassName.get(Map.class),
ClassName.get(String.class),
ClassName.get(RouteMeta.class)
);
ParameterSpec groupParamSpec = ParameterSpec.builder(inputMapTypeOfGroup, "atlas").build();
//定义方法
MethodSpec.Builder loadIntoMethodOfGroupBuilder = MethodSpec.methodBuilder("loadInto")
.addAnnotation(Override.class)
.addModifiers(PUBLIC)
.addParameter(groupParamSpec);
ClassName routeMetaCn = ClassName.get(RouteMeta.class);
for (Element ele : elementsAnnotatedWith) {
if (mTypeUtils.isSubtype(ele.asType(), activityMirror)) {
System.out.println("ele====activity_" + ele.getSimpleName());
Route annotation = ele.getAnnotation(Route.class);
String path = annotation.path();
ClassName className = ClassName.get((TypeElement) ele);
/**
* atlas.put("/test/activity1", RouteMeta.build(RouteType.ACTIVITY, Test1Activity.class, "/test/activity1", "test", new java.util.HashMap(){{put("pac", 9); put("ch", 5); put("fl", 6); put("obj", 10); put("name", 8); put("dou", 7); put("boy", 0); put("objList", 10); put("map", 10); put("age", 3); put("url", 8); put("height", 3); }}, -1, -2147483648));
*/
loadIntoMethodOfGroupBuilder.addStatement(
"atlas.put($S, $T.build($T.class))",
path,
routeMetaCn,
className);
}
System.out.println("ele====" + ele.getSimpleName());
}
System.out.println("ele====over====");
try {
JavaFile.builder(
"com.qf.routes2",
TypeSpec.classBuilder("creteBySelf")
// doc
//.addJavadoc(WARNING_TIPS)
.addSuperinterface(ClassName.get(mElementUtils.getTypeElement("com.example.arouter_appi.IRouteGroup")))
.addModifiers(PUBLIC)
.addMethod(loadIntoMethodOfGroupBuilder.build())
.build()
).build().writeTo(mFiler);
} catch (IOException e) {
e.printStackTrace();
}
}
}
arouter_annotaion module
package com.example.arouter_annotaion;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by qf on 2018/7/25
* 描述: Route
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface Route {
String path();
}
package com.example.arouter_annotaion;
/**
* It contains basic route information.
*
* @author Alex Contact me.
* @version 1.0
* @since 16/8/24 09:45
*/
public class RouteMeta {
private Class> destination; // Destination
private String path; // Path of route
public RouteMeta(Class> cla) {
this.destination = cla;
}
public RouteMeta(){}
public Class> getDestination() {
return destination;
}
public void setDestination(Class> destination) {
this.destination = destination;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public static RouteMeta build(Class> destination) {
return new RouteMeta(destination);
}
}
arouter_appi module
package com.example.arouter_appi;
import android.app.Application;
import android.content.Intent;
import android.widget.Toast;
import com.example.arouter_annotaion.RouteMeta;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
/**
* Created by qf on 2018/7/25
* 描述: Arouter
*/
public class Arouter {
private static Arouter arouter;
public static Map arouters = new HashMap<>();
private static Application mContext;
// ARouter.getInstance().build("/simple/simple1Activity").navigation();
private Arouter(){}
public static Arouter getInstance() {
if (null == arouter) {
arouter = new Arouter();
}
return arouter;
}
public void init(Application context) {
mContext = context;
try {
((IRouteGroup) (Class.forName("com.qf.routes2.creteBySelf").getConstructor().newInstance())).loadInto(arouters);
Toast.makeText(mContext, arouters.size() + "", Toast.LENGTH_SHORT).show();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public void build(String path) {
RouteMeta routeMeta = arouters.get(path);
if (null == routeMeta) return;
Class> destination = routeMeta.getDestination();
if (null != destination) {
Intent intent = new Intent(mContext, destination);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
}
}
package com.example.arouter_appi;
import com.example.arouter_annotaion.RouteMeta;
import java.util.Map;
/**
* Created by qf on 2018/7/25
* 描述: IRouteGroup
*/
public interface IRouteGroup {
/**
* Fill the atlas with routes in group.
*/
void loadInto(Map atlas);
}