Android架构项目代码结构规范--组件化代码 - Go语言中文社区

Android架构项目代码结构规范--组件化代码


前言:

组件化和插件化有什么区别?虽说网上有很多文章但是讲清的聊聊无几,这也是这篇文章的由来。

大方向:组件化是一个项目主管设计管理项目架构方案,而插件化有商务上的合作和局部功能热更换修复等

小方向: 如果是公司app合作,组件化也就是插件化作为别人公司的一个子模块。

简介:组件化是代码上的功能模块化,而插件化是功能上的模块apk插件化。具体看下文

一.原因

项目迭代到一个时期后,随着开发人员的增加,各人的开发风格掺杂到一起,将使代码越发臃肿并且不易维护,这时候公司就会分出一部分人将代码风格统一并且模块化封装和拆分结构。重构代码的核心思想:高内聚低耦合设计思想原则。

Android工程中如何实施两大流派,一个是组件化,一个是插件化。

二.优势

代码重构目的:高内聚,低耦合。规范统一的代码结构,减少更新版本修改代码的工作量

人员效率目的:每个人研发个人的module组件,减少svn或git代码对代码的合并工作,提高分工合作开发效率

bug修复目的:修改代码生产bug最麻烦的就是找bug,由于每个人负责各自的模块代码,方便查找问题的提供的组件接口,快速修正bug。

1、组件化与插件化

 

  上面的图看上去似乎比较清晰,其实容易导致一些误解,有下面几个小问题,图中说的就不太清楚:

  • 组件化是一整个apk如图所示,Android机器人有头有手有脚(各个组件或子模块),手有毛病bug了,就对手部做检查。而各个部件又都依赖于这一整个apk,缺少任何一个器官app都是可以存在并正常运行的。它偏向于编写代码生产机器前的过程。
  • 插件化是多个apk组合在一起,在 组件化中头和手脚可以分开,但是不能作为一个机器人存在。组件化分开都可以作为一个器件(子模块),但是插件化就是将这个器件apk和主人组合在一起,它更偏向于实际的产品使用。

三.组件化架构

1.语言场景:java,cotlin,C或C++(ndk功能开发),mvp或mvvm等

举个栗子1:同事他会cotlin,而我不会,若他在多人开发公共项目代码中使用cotlin语言,所有人都需要学习一边cotlin语言,将会造成其他不会cotlin语言的开发负担。

举个栗子2:同事喜欢mvp模式,另一个同事喜欢用mvvm模式,但是一个项目中多种结构就会显得很杂乱,这个时候如果mvvm的模式只会在那个喜欢mvvm的模块组件中使用,mvp只会喜欢mvp同事的代码模块中,修正过程互不干涉就会使每个人开发更方便,当然建议一种架构模式最好,但是阻挡不了强势的个人思想。

面对团队多人开发时候的争论,这时候如果有一个人做架构处理,就算是cotlin程序猿,ndk底层开发工程师,framework开发部分,以后这代码编写模式不统一都可以解决。并且大公司都有做权限管理,为什么会有呢?一个开发人员就把所有代码都拿到手那大公司还怎么混。因此在做组件化的过程中,可以分权限下载,分工合作开发。

简要图:

详细解析图:

cotlin开发:由于谷歌的推荐导致后来有些公司也开始推崇cotlin语言,而module中可一转化为cotlin形式的module。

cpp开发:一般专门编写c/c++语言的ndk开发人员,主要编写FFmpeg底层功能。这类核心功能开发基本都有一位专门的人员开发。

hook反射:现在已经出现招募framework开发工程师来做市场应用app开发,由于对系统源码了解更多,所以通过各种反射来开发特殊定制功能。

普通java开发:这个也就是我们经常做的开发范围,mvc,mvp,mvvm代码编写模式,都可以直接在module中进行使用,而不会产生冲突,当然推荐是使用统一的模式比较好。

通过上图可以看出,为什么称组件化为架构设计,而不称插件化为架构设计。作为团队开发,如果将分工合作和开发效率做到最高效,所以组件化开发的意义就不言而喻了。当然如果是单人独立开发,博主也可以告诉你,组件化开发依然有意义,可以快速定位模块代码修复bug。

总而言之:

组件化具有强大的兼容性,容纳下整个团队各个开发人员甚至不同开发职能的人员。

组件化具有高效的效率,各种子模块的解耦,就可以快速定位bug,而且子模块的单独编译修改,可以大幅度减少整个项目的编译运行时间(终于不用浪费生命在等as编译了,感谢上天)

 

当然上面所描述的可以了解组件化整体的概念,通过下图,我就可以彻底了解开发步骤了:

四.代码实践:

1、主工程(主module入口):主要负责容纳所有子模块,不包含业务逻辑。主要用于使用组合业务组件、初始化配置和发布应用配置等操作。

2、组件(module/lib):主要实现具体业务逻辑,尽可能保证业务独立性,例如现在手淘这样一个大型的app几乎各个功能块都能够拿出来作为一个独立业务app。但是没有这么大型也可以按照小一些的业务逻辑来区分组件,例如:购物车组件、收银台组件、用户中心组件等,具体更具自己的项目需要来划分。

3、公共库(library):公共使用的application,通用工具类、通用sdk等库,例如eventbus、xutils、okhttp、timber日志工具、自定义工具类等等,这些库可以做成一个公共libcommon。关系则是 主工程依赖组件、组件依赖公共库。

组件化调试分两种模式:1.分模块开发测试模式。2.组合容纳发布模式。
1、分模块开发测试模式:子模块(lib)转化为module模式,子模块module是可以独立运行的,保证高内聚低耦合对其他业务没有依赖就可以独立开发测试。
2、组合容纳发布模式:依赖所有子模块(lib),整合所有模块,所有业务将组合成完整app发布运行。

组件化实质上是一个gradle编写的进阶学习和应用:Android组件化之gradle使用

-----------------------------代码:

步骤1:各个模块的第三方引用库版本号统一放置project根目录gradle.properties,方便各个模块引用相同的参数 根部gradle配置可变参数:

#组件化开发 --module/lib切换
pro_isPlugn=true

步骤2:各子模块build.gradle配置,通过参数pro_isPlugn切换子模块的lib/module模式

一读取gradle.properties中储存String值的pro_isPlugn是否组件化开发,然后对子模块设置为library或者application(module)

if ("true".equals(pro_isPlugn)) {   //组件化步骤1
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}

二.解决包名,要知道library是不需要包名的,那么就可以这样操作:

    defaultConfig {
        if ("true".equals(pro_isPlugn)){  //组件化步骤2
            applicationId "lsh.com.module_mvp"
        }
        ...
    }

三.设置lib模式和子module模式各自对应的AndroidManifest.xml

   sourceSets {
        main { //组件化步骤3
            if ("true".equals(pro_isPlugn)){
                manifest.srcFile 'src/main/AndroidManifest.xml'
            }else {
                manifest.srcFile 'src/main/plugmodule/AndroidManifest.xml'
            }
        }
    }

总体图:

四.plugmodule中的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="lsh.com.module_mvp">

    <application >
        <activity android:name=".MvpActivity">
        </activity>
    </application>

</manifest>

普通的module的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="lsh.com.module_mvp">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name="lsh.com.module_mvp.MvpActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

步骤3:主module判断是否使用子模块,组件化切换后不报错。

一.普通的跳转子模块:注意:将lib切换为module过程中会出现不存在提示红线

startActivity(new Intent(MainActivity.this,CotlinActivity.class));//普通跳转activity,组件化代码切换模式报错,强迫症患者可以选择下面方式

二.反射方式跳转子墨跨:推荐。

        String activityName="lsh.com.module_mvp.MvpActivity";
        try {
            Class clazz = Class.forName(activityName);
            Intent intent=new Intent(MainActivity.this,clazz);
            startActivity(intent);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

三.通过阿里巴巴开源的库ARouter实现跳转,为什么没放进来,复杂化代码,并且个人观点各个子模块要求多升级改动成本大

ARouter.getInstance().build("/MvpActivity/1").navigation();

 

五.作为架构的层次看:

团队开发:容纳所有成员的代码开发,甚至可以两人同时开发一个子模块,切换子模块的代码,快速开发

商业合作:商家合作的插件apk集成可以直接插件化开发。

权限限制:对整个项目做查看的权限处理,防止开发人员的流动,代码的核心保密

预设前景:程序部分功能可以直接插件化,可以重新组合作为新项目。

 

 

插件化见个人下一篇博客。

谢谢观看,有用请点赞和在GitHub上star,作为鼓励!!

个人代码demo下载

 

 

 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/insist_hui/article/details/86478569
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-06-27 21:56:52
  • 阅读 ( 1204 )
  • 分类:架构

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢