移动架构

Android组件化开发实践和案例分享【转】

2020-09-11  本文已影响0人  KtYY

目录介绍

1.为什么要组件化

1.1 为什么要组件化
1.2 现阶段遇到的问题

2.组件化的概念

2.1 什么是组件化
2.2 区分模块化与组件化
2.3 组件化优势好处
2.4 区分组件化和插件化
2.5 application和library

3.创建组件化框架

3.1 传统APP架构图
3.2 组件化需要考虑问题
3.3 架构设计图
3.4 组件通信是通过路由转发
3.5 解决考虑问题
3.6 业务组件的生命周期
3.7 Fragment通信难点

4.实际开发案例

4.1 组件化实践的开源项目
4.1 如何创建模块
4.2 如何建立依赖
4.3 如何统一配置文件
4.4 组件化的基础库
4.5 组件模式和集成模式如何切换
4.6 组件化解决重复依赖
4.7 组件化注意要点
4.8 组件化时资源名冲突
4.9 组件化开发遇到问题

5.组件间通信

5.1 选择那个开源路由库
5.2 阿里Arouter基础原理
5.3 使用Arouter注意事项

6.关于其他

6.1 参考博客链接
6.2 开源项目地址

1.为什么要组件化

1.1 为什么要组件化
APP迭代维护成本增高

投资界,新芽,项目工厂等APP自身在飞速发展,版本不断迭代,新功能不断增加,业务模块数量不断增加,业务上的处理逻辑越变越复杂,同时每个模块代码也变得越来越多,这就引发一个问题,所维护的代码成本越来越高,稍微一改动可能就牵一发而动全身,改个小的功能点就需要回归整个APP测试,这就对开发和维护带来很大的挑战。

多人组合需要组件化

APP 架构方式是单一工程模式,业务规模扩大,随之带来的是团队规模扩大,那就涉及到多人协作问题,每个移动端软件开发人员势必要熟悉如此之多代码,如果不按照一定的模块组件机制去划分,将很难进行多人协作开发,随着单一项目变大,而且Andorid项目在编译代码方面就会变得非常卡顿,在单一工程代码耦合严重,每修改一处代码后都需要重新编译打包测试,导致非常耗时。

1.2 现阶段遇到的问题

结合投资界,新芽客户端分析
代码量膨胀,不利于维护,不利于新功能的开发。项目工程构建速度慢,在一些电脑上写两句代码,重新编译整个项目,测试的话编译速度起码 10-20 分钟,有的甚至更长。
不同模块之间代码耦合严重,有时候修改一处代码而牵动许多模块。每个模块之间都有引用第三方库,但有些第三方库版本不一致,导致打包APP时候代码冗余,容易引起版本冲突。
现有项目基于以前其他人项目基础上开发,经手的人次过多,存在着不同的代码风格,项目中代码规范乱,类似的功能写法却不一样,导致不统一。

2.组件化的概念

2.1 什么是组件化
什么是组件化呢?

组件(Component)是对数据和方法的简单封装,功能单一,高内聚,并且是业务能划分的最小粒度。
组件化是基于组件可重用的目的上,将一个大的软件系统按照分离关注点的形式,拆分成多个独立的组件,使得整个软件系统也做到电路板一样,是单个或多个组件元件组装起来,哪个组件坏了,整个系统可继续运行,而不出现崩溃或不正常现象,做到更少的耦合和更高的内聚。

2.2 区分模块化与组件化
2.3 组件化优势好处

简单来说就是提高工作效率,解放生产力,好处如下:

2.4 区分组件化和插件化
2.5 application和library

在studio中,对两种module进行区分,如下所示
一种是基础库library,比如常见第三方库都是lib,这些代码被其他组件直接引用。
另一种是application,也称之为Component,这种module是一个完整的功能模块。比如分享module就是一个Component。
为了方便,统一把library称之为依赖库,而把Component称之为组件,下面所讲的组件化也主要是针对Component这种类型。

在项目的build.gradle文件中

    //控制组件模式和集成模式
    if (rootProject.ext.isDouBanApplication) {
        //是Component,可以独立运行
        apply plugin: 'com.android.application'
    } else {
        //是lib,被依赖
        apply plugin: 'com.android.library'
    }

3.创建组件化框架

3.1 传统APP架构图

3.2 组件化需要考虑问题

3.3 架构设计图

3.4 组件通信是通过路由转发

3.6 业务组件的生命周期

3.7 Fragment通信难点

4.实际开发案例

4.1 组件化实践的开源项目

4.1 如何创建模块

4.2 如何建立依赖

4.3 如何统一配置文件

4.4 组件化的基础库

4.5 组件模式和集成模式如何切换

4.6 组件化解决重复依赖

4.7 组件化注意要点

4.8 组件化时资源名冲突

4.9 组件化开发遇到问题

5.组件间通信
5.1 选择那个开源路由库

比较有代表性的组件化开源框架有得到得到DDComponentForAndroid、阿里Arouter、聚美Router 等等。
    得到DDComponentForAndroid:一套完整有效的android组件化方案,支持组件的组件完全隔离、单独调试、集成调试、组件交互、UI跳转、动态加载卸载等功能。
    阿里Arouter:对页面、服务提供路由功能的中间件,简单且够用好用,网上的使用介绍博客也很多,在该组件化案例中,我就是使用这个。
    Router:一款单品、组件化、插件化全支持的路由框架

5.2 阿里Arouter基础原理

这里只是说一下基础的思路

    在代码里加入的@Route注解,会在编译时期通过apt生成一些存储path和activityClass映射关系的类文件,然后app进程启动的时候会拿到这些类文件,把保存这些映射关系的数据读到内存里(保存在map里),然后在进行路由跳转的时候,通过build()方法传入要到达页面的路由地址。
        添加@Route注解然后编译一下,就可以生成这个类,然后看一下这个类。如下所示:

    /**
     * DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY AROUTER. */
    public class ARouter$$Group$$video implements IRouteGroup {
      @Override
      public void loadInto(Map<String, RouteMeta> atlas) {
        atlas.put("/video/VideoActivity", RouteMeta.build(RouteType.ACTIVITY, VideoActivity.class, "/video/videoactivity", "video", null, -1, -2147483648));
      }
    }

    ARouter会通过它自己存储的路由表找到路由地址对应的Activity.class(activity.class = map.get(path)),然后new Intent(),当调用ARouter的withString()方法它的内部会调用intent.putExtra(String name, String value),调用navigation()方法,它的内部会调用startActivity(intent)进行跳转,这样便可以实现两个相互没有依赖的module顺利的启动对方的Activity了。
        看_ARouter类中的 _navigation方法代码,在345行。

    private Object _navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
        final Context currentContext = null == context ? mContext : context;

        switch (postcard.getType()) {
            case ACTIVITY:
                // Build intent
                final Intent intent = new Intent(currentContext, postcard.getDestination());
                intent.putExtras(postcard.getExtras());

                // Set flags.
                int flags = postcard.getFlags();
                if (-1 != flags) {
                    intent.setFlags(flags);
                } else if (!(currentContext instanceof Activity)) {    // Non activity, need less one flag.
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                }

                // Set Actions
                String action = postcard.getAction();
                if (!TextUtils.isEmpty(action)) {
                    intent.setAction(action);
                }

                // Navigation in main looper.
                runInMainThread(new Runnable() {
                    @Override
                    public void run() {
                        startActivity(requestCode, currentContext, intent, postcard, callback);
                    }
                });

                break;
            case PROVIDER:
                //这里省略代码
            case BOARDCAST:
            case CONTENT_PROVIDER:
            case FRAGMENT:
                //这里省略代码
            case METHOD:
            case SERVICE:
            default:
                return null;
        }
        return null;
    }

5.3 使用Arouter注意事项

使用阿里路由抽取工具类,方便后期维护!

    首先看一下网络上有一种写法。

    //首先通过注解添加下面代码
    @Route(path = "/test/TestActivity")
    public class TestActivity extends BaseActivity {

    }

    //跳转
    ARouter.getInstance().inject("/test/TestActivity");

    优化后的写法
        下面这种做法,是方便后期维护。

    //存放所有的路由路径常量
    public class ARouterConstant {
        //跳转到视频页面
        public static final String ACTIVITY_VIDEO_VIDEO = "/video/VideoActivity";
        //省略部分diamagnetic
    }

    //存放所有的路由跳转,工具类
    public class ARouterUtils {
        /**
         * 简单的跳转页面
         * @param string                string目标界面对应的路径
         */
        public static void navigation(String string){
            if (string==null){
                return;
            }
            ARouter.getInstance().build(string).navigation();
        }
    }

    //调用
    @Route(path = ARouterConstant.ACTIVITY_VIDEO_VIDEO)
    public class VideoActivity extends BaseActivity {

    }
    ARouterUtils.navigation(ARouterConstant.ACTIVITY_VIDEO_VIDEO);

06.关于其他内容介绍

6.1 关于博客汇总链接

6.1 参考博客链接

6.2 开源项目地址

组件化实践项目开源地址:https://github.com/yangchong2...

转自[https://segmentfault.com/a/1190000017983354]

上一篇下一篇

猜你喜欢

热点阅读