一桃犬、 頁面跳轉(zhuǎn)
兩個(gè)頁面之間的跳轉(zhuǎn)
Intent intent = new Intent();
intent.setClass(A.this, B.class);
startActivity(intent);
如果直接這樣寫卜范,B文件刪除了衔统,會(huì)導(dǎo)致一系列報(bào)紅,然后項(xiàng)目無法編譯。
二锦爵、 使用配置文件
Map<String, Class<?>> clazzMap = new HashMap<>();
clazzMap.put("/a", A.class);
clazzMap.put("/b", B.class);
Intent intent = new Intent();
Class<?> bClass = clazzMap.get("/b");
if(bClass != null) {
intent.setClass(A.this, bClass);
startActivity(intent);
}
維護(hù)一個(gè)classMap舱殿,跳轉(zhuǎn)的時(shí)候從這個(gè)Map里面去找對應(yīng)的頁面,如果沒有找到险掀,可以做一些其他操作沪袭,比如提示,總體上影響不會(huì)太大樟氢,最差也就是無響應(yīng)冈绊。
但是有個(gè)麻煩的地方在于,需要人工維護(hù)這個(gè)Map表埠啃,一旦文件刪除了死宣,但是這個(gè)表沒有更新,還是會(huì)報(bào)錯(cuò)閃退碴开。
三毅该、 apt技術(shù)
什么是apt技術(shù)呢?Annotation processor Tool 注解處理工具潦牛。參照ARouter技術(shù)眶掌,簡單的實(shí)現(xiàn)一個(gè)自動(dòng)生成路由表的工作。
3.1 首先定義一個(gè)注解路由
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface Route {
String path();
}
首先TYPE代表它作用在類上罢绽,CLASS代表編譯時(shí)期仍然存在畏线,可以指定一個(gè)path參數(shù),也就是路由表的key良价。
3.2 定義路由bean
public class RouteMeta {
/**
* 注解使用的類對象
*/
private Class<?> destination;
/**
* 路由地址
*/
private String path;
public RouteMeta(Class<?> destination, String path) {
this.destination = destination;
this.path = path;
}
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;
}
}
保存每一個(gè)路由的信息寝殴,簡單的路由只需要path和class。
既然定義了注解就需要解釋它明垢。
3.3 注解解釋器
@AutoService(Processor.class) //谷歌提供的服務(wù)蚣常,編譯時(shí)期會(huì)自動(dòng)回調(diào)這個(gè)類的各個(gè)方法
public class RouteProcessor extends AbstractProcessor {
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> types = new LinkedHashSet<>();
types.add(Route.class.getCanonicalName()); //指定支持的注解類型
return types;
}
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
//查找到所有被Route注解的class
Set<? extends Element> routes = roundEnvironment.getElementsAnnotatedWith(Route.class);
//自動(dòng)生成文件
processRoute(routes);
return false;
}
private void processRoute(Set<? extends Element> routes) {
try {
//指定生成文件的包名
String packageName = "com.rjp.fastframework";
String activityFileName = packageName + ".IProject";
final String CLASS_SUFFIX = "$Router";
Filer filer = processingEnv.getFiler();
//指定生成的文件名
JavaFileObject javaFileObject = filer.createSourceFile(activityFileName + CLASS_SUFFIX);
//定義writer,開始構(gòu)建java文件
Writer writer = javaFileObject.openWriter();
//構(gòu)建的類名
String clazzName = "IProject" + CLASS_SUFFIX;
writer.write("package " + packageName + ";\n");
writer.write("import com.rjp.expandframework.route.bean.RouteMeta;\n");
writer.write("import com.rjp.expandframework.route.interfaces.IRoute;\n");
writer.write("import java.util.Map;\n");
writer.write("public class " + clazzName + " implements IRoute {\n");
writer.write("@Override\n");
writer.write("public void loadRoute(Map<String, RouteMeta> routes) {\n");
for (Element element : routes) {
String pageClass = element.asType().toString();
Route route = element.getAnnotation(Route.class);
writer.write("routes.put(\"" + route.path() + "\", new RouteMeta(" + pageClass + ".class, \"" + route.path() + "\"));\n");
}
writer.write("}\n");
writer.write("}\n");
writer.close();
}catch (Exception e){
}
}
}
3.4 使用注解
@Route(path = "/main/permission")
public class PermissionActivity extends Activity {}
3.5 自動(dòng)生成路由文件
點(diǎn)擊build痊银,打開/app/build/generated/source/apt/{channel}/debug/抵蚊,你就能看到自動(dòng)生成的文件,里面已經(jīng)自動(dòng)化實(shí)現(xiàn)了以上writer編寫的類代碼溯革。