XRouter 一种基于Arouter的使用封装方案,实现对ARouter的Retrofit式使用。
ARouter是阿里巴巴开源的Android平台中对页面、服务提供路由功能的中间件,没用过的务必点击传送门
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");
NavigatorXRouter基于ARouter提供了针对几个常用场景的解决方案
//声明返回类型为ActivityNavigator,T为需要解析的回传数据类型 @Route(path = "/page/login") ActivityNavigator 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 { @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(); } });
//声明 @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...");
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. 登录拦截
@Route(path = "/page/userInfo", extras = RouteType.LoginFragment) public class UserInfoFragment extends BaseFragment{ ... }
@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拦截
@Route(path = "/page/text", extras = RouteType.Fragment) public class TextFragment extends BaseFragment{ ... }
@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(); } }
@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"; } }
如果你使用混淆并且用到Fragment拦截器的话,需要在混淆配置中添加以下规则:
#XRouter:使用Fragment拦截器 -keep class com.alibaba.android.arouter.facade.Postcard{*;}
小弟不才,第一次分享代码到Github,码代码这茬,一个人容易出事,而且项目来不及写注释,所以特此贴上Q群二维码,如果大家有什么建议和槽点,欢迎能够多多交流。
Demo源码、Demo下载
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/13831.html
摘要:主工程具有和组件进行绑定和解绑的功能。如下图组件化需要考虑问题考虑的问题分而治之,并行开发,一切皆组件。引用阿里的框架,通过注解方式进行页面跳转。 目录介绍 1.为什么要组件化 1.1 为什么要组件化 1.2 现阶段遇到的问题 2.组件化的概念 2.1 什么是组件化 2.2 区分模块化与组件化 2.3 组件化优势好处 2.4 区分组件化和插件化 2.5 applicati...
摘要:说好的分类集合来啦,采用标签云的方式来展示掘金阅读提示点击下文中返回到顶部有分类不合理的地方请提。反编译这个后发现其使用个优质的开源项目掘金是由的开源的一个库,用于构建可预期的和声明式的用户界面。 想不想通过一线互联网公司面试? - Android - 掘金国内一线互联网公司内部面试题库 以下面试题来自于百度、小米、乐视、美团、58、猎豹、360、新浪、搜狐内部题库 熟悉本文中列出的知...
摘要:说好的分类集合来啦,采用标签云的方式来展示掘金阅读提示点击下文中返回到顶部有分类不合理的地方请提。反编译这个后发现其使用个优质的开源项目掘金是由的开源的一个库,用于构建可预期的和声明式的用户界面。 想不想通过一线互联网公司面试? - Android - 掘金国内一线互联网公司内部面试题库 以下面试题来自于百度、小米、乐视、美团、58、猎豹、360、新浪、搜狐内部题库 熟悉本文中列出的知...
摘要:一个精简全面方便的库掘金可设置开启和关闭可设置全局关于六掘金现在的没有几个是不联网的了,在流量费用很高速度一般的今天给用户合理节省流量,以及提高响应速度就显得尤为重要了。内容提要架构浮窗组件开源应用瘦身,从到掘金,大家好,我是。 一个精简、全面、方便的 AndroidLog 库 --ALog - Android - 掘金Functions 可设置Log开启和关闭 可设置Log全局Tag...
摘要:原文地址前言起源组件化方案分析业务组件的划分和代码隔离路由框架基础库的优势简介什么是组件化为什么要组件化分析现有的组件化方案如何选择组件化方案组件化方案描述架构图一览架构图详解宿主层业务层业务模块的拆分基础层核心基础业务公共服务基础组件其他 原文地址: https://www.jianshu.com/p/f67... 0 前言 0.1 起源 0.2 组件化方案分析 0.2....
阅读 663·2021-09-30 09:47
阅读 3125·2021-09-28 09:35
阅读 2068·2021-09-24 10:31
阅读 3625·2021-09-22 15:16
阅读 3190·2021-09-22 10:02
阅读 833·2021-09-22 10:02
阅读 1590·2021-09-08 09:36
阅读 1858·2019-08-30 14:18