XRouter-像Retrofit一样使用阿里开源路由中间件
来源:互联网 发布:mac安装win7虚拟机 编辑:程序博客网 时间:2024/05/29 14:28
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); }}//实现Callbackpublic 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(); } });````<div class="se-preview-section-delimiter"></div>##### b. 获取服务<div class="se-preview-section-delimiter"></div>```java//声明@Route(path = "/service/userService")UserService getUserService();//创建navigatorDemoNavigator navigator = XRouter.getRouter().create(DemoNavigator.class);//获取UserServiceUserService userService = navigator.getUserService();boolean isLogin = userService.isLogin();UserInfo userInfo = userService.getUserInfo();//获取LoggerLogger logger = navigator.getLogger();logger.e("tag", "msg...");
c. 如果还不满足,继续组合打法
import com.mondyxue.xrouter.navigator.Navigator;//声明返回类型为Navigator@Route(path = "/page/login")Navigator toLoginFragment();//创建NavigatorNavigator 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群二维码,如果大家有什么建议和槽点,欢迎能够多多交流。
Demo源码、Demo下载
阅读全文
0 0
- XRouter-像Retrofit一样使用阿里开源路由中间件
- 阿里中间件开源产品
- 如何像阿里工程师一样高效办公?
- 阿里开源Mysql分布式中间件:Cobar
- 阿里开源Mysql分布式中间件:Cobar
- 阿里开源Mysql分布式中间件:Cobar
- 阿里开源Mysql分布式中间件:Cobar
- 像TransactionScope一样使用DbTransaction
- 像黑客一样使用Linux
- 像 IDE 一样使用 vim
- 像阿里一样充满使命愿景和价值观
- 阿里开源消息中间件MetaQ(RocketMQ)简介
- mysql 阿里开源Mysql分布式中间件:Cobar
- PHP5 像使用数组一样使用Memcache
- 像使用水电一样使用云计算
- 像使用vim一样使用firefox
- 像使用IDE一样使用vim
- 像类一样使用结构体
- JS入门之程序设计基础
- POJ 2739
- 了解mian函数
- Unity3D学习记录——NGUI Sprit
- 友元的使用用法:
- XRouter-像Retrofit一样使用阿里开源路由中间件
- python之路——迭代器与可迭代对象
- 剑指offer-不用加减乘除做除法
- #HDU 1421 简单dp
- linux下redis后台运行连接Java代码
- 数据库事务隔离级别-- 脏读、幻读、不可重复读
- 多线程与高并发
- 大整数减法
- java泛型<一>