美文网首页组件化
Android-ARouter组件化

Android-ARouter组件化

作者: JerrySi | 来源:发表于2019-08-07 22:25 被阅读9次

    项目运行到一定程度,功能和人员都会越来越多,另外对于我们公司项目,还出现了多个App有部分业务流程一样的情况。针对这种问题,除了使用私有库的方式抽取公共模块外,还可以通过组件化(也有地方称为模块化)的方式来进行解耦。

    针对我们项目的实际情况,有以下目标要求:

    1. 各个模块可以单独开发,不需要等待其他功能开发完成。
    2. 公共的业务流程代码迁移方便。
    3. 能够控制流程,比如一个页面需要登录才能进入。
    4. 页面可以很方便跳转,比如可以通过支持字符串跳转。
    5. 因为我们项目有部分页面使用了Kotlin,所以需要支持Kotlin。

    经过调研,发现ARouter能很好的解决我们上面的痛点。ARouter网上的资料已经很完善了,下面主要讲讲,针对我们项目,我们是如何使用它的。

    页面跳转

    1. 定义路由格式:为了避免页面路由冲突,定义路由格式:当前Module名字+当前文件名
      通过配置gradle,让当前Module名字自动生成
    buildConfigField("String",
            "MODULE_SHORT_NAME",
            "\""+(project.getName().substring(project.getName().lastIndexOf(".") + 1))+"\"")
    
    1. 配置页面路由:
    @Route(path = "/" + BuildConfig.MODULE_SHORT_NAME + "/XXXActivity")
    public class XXXActivity extends BaseActivity {
      /***/
    }
    
    1. 定义公共路由配置文件
    public interface RouterConstant {
    
        /*其他Module*/
    
        // MODULE_NAME 改成自己Module名字
        interface MODULE_NAME {
            // MODULE_SHORT_NAME改成自己Module名字
            String BASE = "/MODULE_SHORT_NAME/";
            // XXXActivity改成自己Activity名字
            String XXX = BASE + "XXXActivity";
        }
    }
    
    1. 页面跳转
      根据第3步定义的配置文件获取配置,最终跳转页面XXXActivity2。
    ARouter.getInstance()
                .build(RouterConstant.MODULE_NAME.XXX)
                .navigation(XXXActivity2.this);
    

    页面跳转拦截器

    IInterceptor一旦定义,页面跳转的时候都会进入拦截器,所以需要在拦截器中判断是否真的要进入拦截器。

    @Interceptor(priority = 1, name = "登录拦截器")
    public class LoginIInterceptor implements IInterceptor {
        
        public static final String IS_CHECK_LOGIN = "IS_CHECK_LOGIN";
        private Postcard postcard;
        private InterceptorCallback callback;
        private Context context;
    
        @Override
        public void process(Postcard postcard, InterceptorCallback callback) {
    
            if (callback != null) {
                if (postcard != null && postcard.getExtras() != null) {
    
                    // 判断是否需要检查登录
                    boolean isCheckLogin = postcard.getExtras().getBoolean(IS_CHECK_LOGIN);
    
                    try {
                        // 如果需要检查登录 而且 当前没有登录
                        if (isCheckLogin && !LoginInfoManager.isLogin(context)) {
    
                            // 暂存跳转数据和回调流程
                            this.postcard = postcard;
                            this.callback = callback;
    
                            // 跳转登录页面
                            ARouterWrapper.build(RouterConstant.LOGIN.LOGIN)
                                    .withFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP)
                                    .navigation(context, new NavCallback() {
                                        @Override
                                        public void onArrival(Postcard postcard) {
    
                                        }
                                    });
                            return;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        callback.onContinue(postcard);
                    }
    
                }
            }
            // 处理完成,交还控制权
            callback.onContinue(postcard);
        }
    
        @Override
        public void init(Context context) {
            this.context = context;
            // 添加登录成功消息监听
            EventBus.getDefault().register(this);
        }
    
        @Subscribe
        public void onEventBusReceive(EventBusHandler eventBusHandler) {
            /*判断消息类型*/
            /*处理逻辑*/
            /*释放对象*/
        }
    }
    

    在要检查登录的页面跳转的时候,添加参数”IS_CHECK_LOGIN“。在拦截器里面判断是否需要验证登录,如果需要验证登录而且当前没有登录,跳转登录页面。登录成功后通过EventBus发送消息,在拦截器里面进行监听,处理相关业务逻辑,继续之前的操作。其他拦截器的逻辑也是类似处理流程,这里就不展开了。

    提供程序接口IProvider

    当项目中出现下面情况的时候,IProvider就派上用场了。

    • A Module需要调用或者使用 B Module里面的方法
    1. 在项目公共配置里面定义IProvider
    public interface XXXProvider extends IProvider {
        View createSomeView(Context context);
        void doSometing();
    }
    
    1. 在具体的Module里面实现XXXProvider
    @Route(path = "/" + BuildConfig.MODULE_SHORT_NAME + "/XXXProviderImpl")
    public class XXXProviderImpl implements XXXProvider {
    
        @Override
        public View createSomeView(Context context) {
            /*创建View返回*/
        }
    
        @Override
        public void doSometing() {
            /*处理逻辑*/
        }
    }
    
    1. 调用XXXProvider里面方法
        // 通过注解获取对象provider,调用XXXProvider里面方法
        @Autowired
        XXXProvider provider;
    

    通过上面处理,最终App结构如下:


    image.png

    相关文章

      网友评论

        本文标题:Android-ARouter组件化

        本文链接:https://www.haomeiwen.com/subject/mavodctx.html