博客
关于我
面试官,怎样实现 Router 框架?
阅读量:144 次
发布时间:2019-02-26

本文共 4512 字,大约阅读时间需要 15 分钟。

基于注解的路由框架实现:从零到一的全解析

在Android开发中,模块化和组件化是永恒的话题。随着项目复杂性的不断增加,路由框架逐渐成为开发中不可或缺的工具。然而,如何设计一个高效、灵活的路由框架却是一个值得深入探讨的问题。

本文将从零开始,详细介绍如何设计并实现一个基于注解的路由框架,涵盖路由跳转、模块化支持、结果回调等核心功能。


基本使用

1. 注解定义

首先,我们需要定义一个路由框架所需的注解。通过注解,我们可以轻松地定义路由路径和模块信息。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface Route {
String path();
}
@Retention(RetentionPolicy.CLASS)
public @interface Modules {
String[] value();
}
@Retention(RetentionPolicy.CLASS)
public @interface Module {
String value();
}

2. 路由初始化

在路由框架的核心文件中,我们定义了路由的初始化逻辑。通过扫描注解信息,我们可以动态地生成路由映射。

public class Router {
private static final String TAG = "Router";
private static final Router instance = new Router();
private Map
> routeMap = new HashMap<>();
private boolean loaded;
private Router() {
}
public static Router getInstance() {
return instance;
}
public void init() {
if (loaded) {
return;
}
RouterInit.init();
loaded = true;
}
}

模块化支持

路由框架支持多模块使用,通过注解可以轻松定义模块信息。

1. 主模块初始化

在主模块中,使用@Modules注解定义总共有多少个模块,并在每个模块中使用@Module注解指定模块名称。

@Modules({"app", "moudle1"})
@Module("app")
public class RouterApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
Router.getInstance().init();
}
}

2. 子模块路由定义

在子模块中,使用@Route注解定义路由路径,并结合模块信息实现路由映射。

@Route(path = "my/activity/main")
@Module("moudle1")
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_2);
}
}

路由跳转

1. 手动跳转

通过Router.getInstance().build("路由路径").navigation(this)实现路由跳转。

Router.getInstance().build("activity/main").navigation(this);

2. 自定义跳转

如果需要自定义跳转,可以通过Router.getInstance().add("路由路径", Activity.class)将路由映射到特定活动。

Router.getInstance().add("activity/three", ThreeActivity.class);
Router.getInstance().build("activity/three").navigation(this);

结果回调

路由框架支持跳转结果回调,包括beforeOpenafterOpennotFinderror等方法。

Router.getInstance().build("my/activity/main", new RouterCallback() {
@Override
public boolean beforeOpen(Context context, Uri uri) {
Log.i(TAG, "beforeOpen: uri=" + uri);
return false;
}
@Override
public void afterOpen(Context context, Uri uri) {
Log.i(TAG, "afterOpen: uri=" + uri);
}
@Override
public void notFind(Context context, Uri uri) {
Log.i(TAG, "notFind: uri=" + uri);
}
@Override
public void error(Context context, Uri uri, Throwable e) {
Log.i(TAG, "error: uri=" + uri + ";e=" + e);
}
}).navigation(this);

原理说明

1. 注解处理

路由框架通过扫描注解信息,生成相应的路由映射文件。RouterProcessor类负责解析注解信息,并生成路由初始化文件。

public class RouterProcessor extends AbstractProcessor {
private Messager messager;
private Filer mFiler;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
messager = processingEnv.getMessager();
mFiler = processingEnv.getFiler();
UtilManager.getMgr().init(processingEnv);
}
@Override
public Set
getSupportedAnnotationTypes() {
Set
annotations = new LinkedHashSet<>();
annotations.add(Route.class.getCanonicalName());
annotations.add(Module.class.getCanonicalName());
annotations.add(Modules.class.getCanonicalName());
return annotations;
}
}

2. 路由映射生成

通过RouterProcessor扫描注解信息,生成路由映射文件。例如,定义的路由信息会被编译成RouterMapping_app类。

public class RouterMapping_app {
public static void map() {
Router.getInstance().add("activity/main", MainActivity.class);
Router.getInstance().add("activity/one", OneActivity.class);
Router.getInstance().add("activity/two", TwoActivity.class);
}
}

路由API

路由框架提供了丰富的API接口,包括路由初始化、跳转和结果回调等。

public class Router {
private static final String TAG = "ARouter";
private static final Router instance = new Router();
private Map
> routeMap = new HashMap<>();
private boolean loaded;
private Router() {
}
public static Router getInstance() {
return instance;
}
public void init() {
if (loaded) {
return;
}
RouterInit.init();
loaded = true;
}
}

总结

通过以上实现,我们可以清晰地看到一个基于注解的路由框架是如何工作的。从注解扫描到路由映射再到路由执行,每个环节都经过了严格的设计和优化。路由框架不仅支持单模块使用,还可以扩展到复杂的多模块场景,满足开发者的实际需求。

如果你对路由框架的实现感兴趣,或者需要更多的技术支持,可以前往相关技术社区和文档进行深入学习和交流。

转载地址:http://uluz.baihongyu.com/

你可能感兴趣的文章
mysql 更新子表_mysql 在update中实现子查询的方式
查看>>
MySQL 有什么优点?
查看>>
mysql 权限整理记录
查看>>
mysql 权限登录问题:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
查看>>
MYSQL 查看最大连接数和修改最大连接数
查看>>
MySQL 查看有哪些表
查看>>
mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
查看>>
MySql 查询以逗号分隔的字符串的方法(正则)
查看>>
MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT 、分页查询的优化、合理使用连接、子查询的优化)(上)
查看>>
mysql 查询数据库所有表的字段信息
查看>>
【Java基础】什么是面向对象?
查看>>
mysql 查询,正数降序排序,负数升序排序
查看>>
MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)...
查看>>
mysql 死锁 Deadlock found when trying to get lock; try restarting transaction
查看>>
mysql 死锁(先delete 后insert)日志分析
查看>>
MySQL 死锁了,怎么办?
查看>>
MySQL 深度分页性能急剧下降,该如何优化?
查看>>
MySQL 深度分页性能急剧下降,该如何优化?
查看>>
MySQL 添加列,修改列,删除列
查看>>
mysql 添加索引
查看>>