XRouter-像Retrofit一样使用阿里开源路由中间件
XRouter
一种基于Arouter的使用封装方案,实现对ARouter的Retrofit式使用。
ARouter是阿里巴巴开源的Android平台中对页面、服务提供路由功能的中间件,没用过的务必点击传送门
基础功能
1. 依赖配置
android {
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = [ moduleName : project.getName() ]
}
}
}
}
dependencies {
//ARouter
compile 'com.alibaba:arouter-api:x.x.x'
annotationProcessor 'com.alibaba:arouter-compiler:x.x.x'
//XRouter
compile 'com.mondyxue:xrouter:1.0-SNAPSHOT@aar'
}
repositories {
maven {
//XRouter
url "https://raw.githubusercontent.com/MondyXue/Maven/master"
}
}
2. 给目标页面添加注解
import com.alibaba.android.arouter.facade.annotation.Route;
@Route(path = "/page/browser")
public class WebViewActivity extends BaseActivity{
...
}
3. 在Application中添加初始化代码
//初始化uri信息
XRouter.setScheme("xrouter");
XRouter.setAuthority("mondyxue.github.io");
//XRouter初始化
XRouter.init(DemoApplication.this);
4. 声明Navigator接口
import com.mondyxue.xrouter.annotation.Extra;
import com.mondyxue.xrouter.annotation.Route;
public interface WebNavigator{
@Route(path = "/page/browser")
void openUrl(@Extra("url") String url);
}
5. 发起路由
XRouter.getRouter()
.create(WebNavigator.class)
.openUrl("https://github.com/Alibaba/ARouter");
其它使用
XRouter基于ARouter提供了针对几个常用场景的解决方案
Navigator
a. startActivityForResult
//声明返回类型为ActivityNavigator<T>,T为需要解析的回传数据类型
@Route(path = "/page/login")
ActivityNavigator<UserInfo> toLoginFragment();
//复写Activity和Fragment基类中的onActivityResult方法
public abstract class BaseActivity extends FragmentActivity{
...
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
//XRouter处理回调逻辑
XRouter.getRouter()
.getActivityManager()
.onActivityResult(BaseActivity.this, requestCode, resultCode, data);
}
}
//实现Callback
public abstract class UserInfoCallback extends RouteCallback<UserInfo>{
@Override public UserInfo parseData(int requestCode, int resultCode, Intent data){
return (UserInfo) data.getSerializableExtra(Extras.UserInfo);
}
}
//路由发起
XRouter.getRouter()
create(DemoNavigator.class)
toLoginFragment()
startActivityForResult(new UserInfoCallback(){
@Override public void onResponse(@NonNull UserInfo data){
Toast.makeText(MainActivity.this, "login success: " + data.toString(), Toast.LENGTH_SHORT).show();
}
});
b. 获取服务
//声明
@Route(path = "/service/userService")
UserService getUserService();
//创建navigator
DemoNavigator navigator = XRouter.getRouter().create(DemoNavigator.class);
//获取UserService
UserService userService = navigator.getUserService();
boolean isLogin = userService.isLogin();
UserInfo userInfo = userService.getUserInfo();
//获取Logger
Logger logger = navigator.getLogger();
logger.e("tag", "msg...");
c. 如果还不满足,继续组合打法
import com.mondyxue.xrouter.navigator.Navigator;
//声明返回类型为Navigator
@Route(path = "/page/login")
Navigator toLoginFragment();
//创建Navigator
Navigator navigator = XRouter.getRouter()
.create(DemoNavigator.class)
.toLoginFragment();
//通过Navigator调用支持方法
Uri uri = navigator.uri();
Intent intent = navigator.intent();
Fragment fragment = navigator.fragment();
IProvider provider = navigator.service();
navigator.startActivity();
RouteType
import com.mondyxue.xrouter.constant.RouteType;
import com.alibaba.android.arouter.facade.annotation.Route;
//在ARouter的Route注解中
//RouteType中有几个辅助flag值,可用于ARouter的Route注解中的extras值Route(extras=...)
RouteType.GreenChannel//绿色通道,不经过拦截器
RouteType.Fragment//Fragment标记
RouteType.Activity//Activity标记
RouteType.Service//标记是否为实现了IProvider的服务类
RouteType.WithinTitlebar//标记此页面是否已有标题栏(Toolbar等)
RouteType.Login//标记访问此页面是否需要登录权限
RouteType.Main//标记此页面是否为App首页
//组合打法
RouteType.TitlebarFragment = Fragment | WithinTitlebar;
RouteType.LoginActivity = Activity | Login;
1. 登录拦截
a. 配置extras标记
@Route(path = "/page/userInfo", extras = RouteType.LoginFragment)
public class UserInfoFragment extends BaseFragment{
...
}
b. 实现登录拦截器
@Interceptor(priority = 4, name = "LoginInterceptor")
public class LoginInterceptor extends com.mondyxue.xrouter.interceptor.LoginInterceptor implements IInterceptor{
//返回当前用户是否已登录
@Override public boolean isLogin(){
return XRouter.getRouter()
.create(DemoNavigator.class)
.getUserService()
.isLogin();
}
//调用登录服务,在登录回调中执行原拦截器回调
@Override protected void onInterrupt(final Postcard postcard, final InterceptorCallback callback){
XRouter.getRouter()
.create(DemoNavigator.class)
.toLoginFragment()
.startActivityForResult(new UserInfoCallback(){
@Override public void onResponse(@NonNull UserInfo data){
postcard.withSerializable(Extras.UserInfo, data);
callback.onContinue(postcard);
}
@Override public void onError(Throwable throwable){
callback.onInterrupt(throwable);
}
@Override public void onCancel(){
callback.onInterrupt(new RuntimeException("login cancel!"));
}
});
}
}
2. Fragment拦截
a. 配置extras标记
@Route(path = "/page/text", extras = RouteType.Fragment)
public class TextFragment extends BaseFragment{
...
}
b. 配置Fragment容器Activity
@Route(path = "/page/contanier", extras = RouteType.Activity | RouteType.GreenChannel)
public class ContanierActivity extends BaseActivity{
@Override protected int getRootLayout(){
//RouteType.Titlebar标记值可通过此方式获取
boolean withinTitlebar = getIntent().getBooleanExtra(RouteExtras.WithinTitlebar, false);
//根据标记值决定容器的布局是否有标题栏
return withinTitlebar ? R.layout.activity_contanier
: R.layout.activity_contanier_within_titlebar;
}
@Override protected void init(){
Intent intent = getIntent();
boolean withinTitlebar = intent.getBooleanExtra(RouteExtras.WithinTitlebar, false);
if(!withinTitlebar){
//判断并设置Title
String title = intent.getStringExtra(RouteExtras.Title);
((TextView) findViewById(R.id.tv_title)).setText(title);
}
//获取拦截器中传过来的Fragment路由path
String path = intent.getStringExtra(RouteExtras.PathTo);
if(!TextUtils.isEmpty(path)){
//使用XRouter根据path获取fragment实例
final Fragment fragment = XRouter.getRouter().build(path).navigator().fragment();
if(fragment != null){
fragment.setArguments(intent.getExtras());
runOnUiThread(new Runnable(){
@Override public void run(){
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fl_contanier, fragment)
.hide(fragment)
.show(fragment)
.commitAllowingStateLoss();
}
});
return;
}
}
finish();
}
}
c. 实现Fragment拦截器
@Interceptor(priority = 8, name = "FragmentInterceptor")
public class FragmentInterceptor extends com.mondyxue.xrouter.interceptor.FragmentInterceptor implements IInterceptor{
@Override protected String getFragmentContainerPath(){
//返回Fragment容器Activity路径
return "/page/contanier";
}
}
还有个MainIntercepter,可用于主界面(RouteType.Main)的跳转拦截,详见Demo代码
混淆
如果你使用混淆并且用到Fragment拦截器的话,需要在混淆配置中添加以下规则:
#XRouter:使用Fragment拦截器
-keep class com.alibaba.android.arouter.facade.Postcard{*;}
后话
小弟不才,第一次分享代码到Github,码代码这茬,一个人容易出事,而且项目来不及写注释,所以特此贴上Q群二维码,如果大家有什么建议和槽点,欢迎能够多多交流。

XRouter-像Retrofit一样使用阿里开源路由中间件的更多相关文章
- 实战!Spring Boot 整合 阿里开源中间件 Canal 实现数据增量同步!
大家好,我是不才陈某~ 数据同步一直是一个令人头疼的问题.在业务量小,场景不多,数据量不大的情况下我们可能会选择在项目中直接写一些定时任务手动处理数据,例如从多个表将数据查出来,再汇总处理,再插入到相 ...
- 组件化框架设计之阿里巴巴开源路由框架——ARouter原理分析(一)
阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680 背景 当项目的业务越来越复杂,业务线越来越多的时候,就需要按照业 ...
- JVM 性能调优实战之:使用阿里开源工具 TProfiler 在海量业务代码中精确定位性能代码
本文是<JVM 性能调优实战之:一次系统性能瓶颈的寻找过程> 的后续篇,该篇介绍了如何使用 JDK 自身提供的工具进行 JVM 调优将 TPS 由 2.5 提升到 20 (提升了 7 倍) ...
- 阿里开源的热补丁框架AndFix使用教程
阿里巴巴推出的AndFix框架 首次给出大家这个框架的地址:https://github.com/alibaba/AndFix 对源码比较感兴趣的同学们可以自行研究代码 AndFix原理介绍 AndF ...
- 如何找到fastjson.jar这个阿里开源的jar包
如何找到fastjson.jar这个阿里开源的jar包 转载 https://blog.csdn.net/AngelLover2017/article/details/84261261 Java编程中 ...
- Android热修复之 - 阿里开源的热补丁
1.1 基本介绍 我们先去github上面了解它https://github.com/alibaba/AndFix 这里就有一个概念那就AndFix.apatch补丁用来修复方法,接下来我们看看到底是 ...
- 初识阿里开源诊断工具Arthas
上个月,阿里开源了一个名为Arthas的监控工具.恰逢近期自己在写多线程处理业务,由此想到了一个问题. 如果在本机开发调试,IDE可以看到当前的活动线程,例如IntelliJ IDEA,线程是运行还是 ...
- 使用阿里开源工具 TProfiler 在海量业务代码中精确定位性能代码 (jvm性能调优)
技术交流群:233513714 本文是<JVM 性能调优实战之:一次系统性能瓶颈的寻找过程> 的后续篇,该篇介绍了如何使用 JDK 自身提供的工具进行 JVM 调优将 TPS 由 2.5 ...
- 重磅发布:阿里开源 OpenJDK 长期支持版本 Alibaba Dragonwell
原文地址:https://yq.aliyun.com/articles/694603 本文作者:阿里开源 本文来自云栖社区合作伙伴"阿里系统软件技术",了解相关信息可以关注&qu ...
随机推荐
- zookeeper 应用场景概述
Zookeeper主要可以干哪些事情:配置管理,名字服务,提供分布式同步以及集群管理. 一 .配置管理 在我们的应用中除了代码外,还有一些就是各种配置.比如数据库连接,远程服务访问地址等.一般我们都是 ...
- 开始学习机器学习,从Ng的视频开始
时隔开5个月,忙完了考研和毕设后终于有时间搞自己想搞得,研究生导师方向是图像处理与机器学习结合,重新开工 何为机器学习? 对于机器学习(Machine Learning)的定义大体上有两种,第一种是美 ...
- jquery.qrcode.min.js(支持中文转化二维码)
详情请看:http://www.ncloud.hk/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/jqueryqrcodeminjs/ 今天还是要讲一下关于二维码的知识,前 ...
- MongoDB--数据库与Collection注意事项
<h2> <strong>注意事项:</strong></h2>1.数据库名注意应该全部小写,不能包含空格,最大长度为64K名称<br /& ...
- iOS内购图文流程(2017)
什么是内购? 只要在iPhone App上购买的不是实物产品(也就是虚拟产品如qq币.虎牙币.电子书......) 都需要走内购流程,苹果这里面抽走三成. 使用内购需要走的流程. 1,填写协议,税 ...
- 使用jQuery筛选排除元素以修改指定标签的属性
简单案例: $(function(){ $("td[id][id!='']").click(function(){ //你的逻辑 }); }); 上述代码,有id且id不为空的td ...
- ajax数据请求3(数组json格式)
ajax数据请求3(数组json格式) <!doctype html> <html> <head> <meta charset="utf-8&quo ...
- [Android FrameWork 6.0源码学习] LayoutInflater 类分析
LayoutInflater是用来解析XML布局文件,然后生成对象的ViewTree的工具类.是这个工具类的存在,才能让我们写起Layout来那么省劲. 我们接下来进去刨析,看看里边的奥秘 //调用i ...
- java程序员常见面试题目
答:每当程序出现异常之后,如果程序没有进行相应的处理,则程序会出现中断现象.实际上,产生了异常之后,JVM会抛出一个异常类的实例化对象,如果此时使用了try语句捕获的话,则可以进行异常的处理,否则 ...
- 浅谈Ajax 异步的几点细节
1.浏览器执行到Ajax代码的这行语句的时候,发出了一个HTTP请求,欲想请求服务器上的数据.服务器此时开始I/O,所谓的I/O就是磁盘的读写,需要花费一些时间,所以不会立即产生下行的HTTP报文: ...