精华内容
下载资源
问答
  • 组件化开发系列文章 1. Android组件化开发之一:为什么要进行组件化开发 2. Android组件化开发之二:组件化架构 3. Android组件化开发之三:组件化开发手册 4. Android组件化开发之四:组件化填坑之旅 5. Android...

    我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版,欢迎购买。点击进入详情

    组件化开发系列文章

    1. Android组件化开发之一:为什么要进行组件化开发
    2. Android组件化开发之二:组件化架构
    3. Android组件化开发之三:组件化开发手册
    4. Android组件化开发之四:组件化填坑之旅

    5. Android组件化开发之五:组件化开发实战Demo

    开发模式为project

    新建一个项目专门用来对此业务模块的组件化进行开发,项目内可分为application工程(app)和library工程(module)。
    app工程主要用来调测module工程使用,比如测试module工程的接口功能实现。
    module工程主要实现业务逻辑,同时可以含有UI实现,即对外提供的UI,包括但不限于activity和fragment;

    当项目调测完毕时,将module工程编译生成aar文件,并且通过gradle脚本提交到maven仓库。

     

    开发模式为module

    需要在现有的主项目里面新建module工程,每一个module工程就是一个业务组件。
    module工程的开发模式:
    main:作为项目的组建时使用;main里面的provider代表这个组件对外开放(组件间通信)的能力;每一个provider需要在ServiceManager里面进行声明并交由其管理;
    debug:作为独立模块运行时使用,需要新建一个application和androidmanifest文件;
    总的来说,以debug模式和release模式去区分,在debug模式下,各个业务线作为application可以单独运行,而在release模式下,则作为library,可以提供给主app进行依赖。
    这样一来就可以做到每个业务线的平行开发,在Release模式下再合到一起,非常的灵活。
    现有项目的app模块:
    app模块是一个壳工程,主要负责app的配置(build.gradle、AndroidManifest.xml)、初始化(AppApplication)工作;
    app模块的AppApplication需要通过ModuleOptions.ModuleBuilder(this)的addModule方法将各个组件的引用添加进来;
    base-core组件
    base-core组件需包含ARouter管理。

     

     

    开放模式为公开

    一般此种模式下,是对外提供jar或aar包供其它主工程或库工程引用。
    如果存在引用关系,比如A引用B,那么A可以直接调用B中的方法或页面,也就不存在ARouter来搭建桥梁;

     

     

    开放模式为内部

    一般此种模式下,是在项目内部的module工程(此module工程也可以在外部独立新建一个项目来实现,但是必须使用主项目同样的路由架构比如ARouter);
    module之间不存在引用关系,因此必须使用路由架构比如ARouter来实现。

     

     

    关于ARouter

    不同的模块负责自己的业务实现,不和其他模块有依赖关系的存在,也就是模块之间没有直接的compile关系。
    假如这个模块需要启动别的模块的Activity或者是调用别的模块的方法,我们就通过ARouter提供的方法去实现。
    router的管理在base-core组件下的router文件夹内;
    provider:各个组件定义的接口,包含对外提供的能力;
    module:一般命名为xxService,是各个组件对外调用的服务入口;
    ServiceManager:通过annotation实例化各个组件的provider并统一管理;通过ServiceManager对目标组件provider的调用,实现跨组件通信;

    展开全文
  • 组件化开发系列文章 1. Android组件化开发之一:为什么要进行组件化开发 2. Android组件化开发之二:组件化架构 3. Android组件化开发之三:组件化开发手册 4. Android组件化开发之四:组件化填坑之旅 5. Android...

    我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版,欢迎购买。点击进入详情

    组件化开发系列文章
    1. Android组件化开发之一:为什么要进行组件化开发
    2. Android组件化开发之二:组件化架构
    3. Android组件化开发之三:组件化开发手册
    4. Android组件化开发之四:组件化填坑之旅

    5. Android组件化开发之五:组件化开发实战Demo

    现状

     

    随着APP业务的不断增加,版本不断迭代,APP越来越臃肿,随之而来的问题也逐步呈现出来;

    问题1、APP中业务代码的增量叠加,而且各种业务代码混合在一个模块里面,开发人员在开发、调测过程中势必会带来效率上的影响;比如定位一个A业务的问题,可能需要在十个业务代码混合的模块里面寻找和跳转。

     

    问题2、工程师需要了解各个业务的功能,避免代码的改动而影响其它的业务功能,势必无形中增加了项目维护的成本。

     

    问题3、开发和调测一个业务功能的时候,需要整体编译APP,由于代码量越大,编译速度会相应地变慢,导致一个简单功能的的修改可能就要花费几分钟的时间编译整个APP,极大地影响开发效率。

     

    问题4、内部项目没有一个统一的快速开发框架,每个项目采用的技术实现方式都不一样,每个开发人员的编码风格也不一致,导致每开发一个新项目都要重新编码、重复造轮子,而且也造成了开发人员在项目之间的流动困难。

     

    问题5、有一些内部项目可以共用的功能模块,同样混杂于各个app工程里面,这部分内容实际上可以考虑抽取出来,封装成独立的公用组件,供内部各个项目使用。

     

    下图是一个典型的APP结构图,我们不妨对照下自己的APP工程看看:

     

     

     

    目标

     

    我们针对上述问题现状进行有针对性地改造。

    我们考虑采取以下几种方式来实现:

     

    解决方案1:组件化

    针对问题1、问题2、问题3,我们可以考虑以组件化的形式来解决。

    组件化的目标是要告别APP的臃肿,APP的业务迭代不应该以牺牲APP的臃肿为代价。

    各个业务组件相对独立,业务组件在组件模式下可以独立运行,自成一个APP,而在集成模式下可以作为一个被依赖的aar库文件存在,集成进一个完整的APP当中;

     

    解决方案2:公用组件(含快速开发框架)

    针对问题4、问题5,我们考虑开发一套适合于内部移动端快速迭代开发使用的框架。

    快速开发框架可以细化为不同的部分,包括android UI、网络请求、数据库持久化、图片处理、View、工具类、sdk、内部统一风格组件等;

    快读开发框架包括但不限于通用功能,如果是部门内部项目中通用的功能,也可以独立出来成为一个通用的库存在。

     

    我们期望的一个优秀的APP结构是下面这样的:

    APP拆分成三大块内容:

    一个是APP壳工程,提供组装各个业务组件的功能,以及一些初始化的操作;

    一个是业务组件工程,每一个具体的业务放在单独的业务组件中;

    一个是公用组件工程,可以提供给本项目各个业务组件使用,也可以提供给其它项目使用;

     

    展开全文
  • 公司项目需要引用公司内部开发的IM组件组件AAR包的形式进行引入,由于IM组件相当于一个完整的项目,所以用到的jar包比较多,比如fastjson、okhttp、glide。 这些jar包在项目中的common库中也有引用,所以造成了...

    背景:

    公司项目需要引用公司内部开发的IM组件,组件以AAR包的形式进行引入,由于IM组件相当于一个完整的项目,所以用到的jar包比较多,比如fastjson、okhttp、glide。

    这些jar包在项目中的common库中也有引用,所以造成了冲突。


    问题:

    引入aar包之后的gradle编译报如下错误,注意jar包冲突的的错误每次都只会报一个,其实可能存在多个冲突。从log中可以看出冲突的是okhttp这个jar包的引入导致。

    Error:Execution failed for task ':app:transformClassesWithJarMergingForZhgyDebug'.
    > com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry: okhttp3/Address.class


    Error:Execution failed for task ':app:transformClassesWithJarMergingForZhgyDebug'.
    > com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry: com/google/gson/annotations/Expose.class

    原因:

    Android在打包编译的时候会将aar包中的资源文件一并打入包中,这个时候第三方包的包名和类名都完全一致,这会导致在寻找需要的类的时候出现问题。

    所以这里我们就有两个不同的解决方案。

    1、引用jar包的源码,修改源码的包名。

    2、使用gradle的配置exclude掉重复的jar包。


    解决方法:

    在app的gradle中添加如下配置

    configurations {
        compile.exclude module: 'okhttp'
        compile.exclude module: 'fastjson'
        compile.exclude module: 'glide'
    }

    gradle针对jar包重复的问题的解决,详细的介绍可以看官方的文章

    https://docs.gradle.org/current/userguide/dependency_management.html


    展开全文
  • 组件化开发系列文章 1. Android组件化开发之一:为什么要进行组件化开发 2. Android组件化开发之二:组件化架构 3. Android组件化开发之三:组件化开发手册 4. Android组件化开发之四:组件化填坑之旅 5. Android...

    我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版,欢迎购买。点击进入详情

    组件化开发系列文章

    1. Android组件化开发之一:为什么要进行组件化开发
    2. Android组件化开发之二:组件化架构
    3. Android组件化开发之三:组件化开发手册
    4. Android组件化开发之四:组件化填坑之旅

    5. Android组件化开发之五:组件化开发实战Demo

    序号

    名称

    坑深度

    内容

    1

    JPush

    极光推送的配置文件不能放在library工程里面,必须放到application工程中。
    2

    Resource IDs

    Resource IDs cannot be used in a switch statement in Android library modules.

    Android Studio里面快捷转换方式:选中“switch”,ALt+Enter同时选中,弹出对话框,选择“Replace 'switch' with 'if'”。

    3

    ButterKnife引用

    在library工程中,提示:Attribute value must be constant。

    这是因为library中R.id.xxx 取R中变量的时候并非是final类型。

    解决方法:

    ButterKnife在8.0版本以上支持library内使用视图注入,原先app用的是7.x版本的,所以要先升级到8.x版本。

    期间还需要将以前的R用R2代替。

    有时候AS识别不了R2,需要多build几次。

    4

    ButterKnife点击

    接上所述,正常情况下,Butterknife的点击事件是这样的:

    @OnClick({R2.id.btn_login, R2.id.btn_regist})
    public void onClick(View view) {
    int i = view.getId();
    if (i == R2.id.btn_login) {

    ......

    但现在的问题是,view.getId()获得的是R类中的id,而不是R2类中的id,特么的巨坑!!!

    解决方法:

    1、使用RCaster类做一个R到R2的转换。

    2、不用ButterKnife响应click事件,就用android原生的onClick。

    5

    Dagger2

    Dagger2在各个组件工程里面有时候不会生成对应的文件,有时候生成了文件AS不能立刻识别,要等一段时间,可能这是dagger2和AS之间的bug吧。

    解决方法:

    第一步、在build-generated-source-apt-release下找到对应的daggerXXXX文件,然后双击打开。

    第二步、点击Build–Make Module XXXX。

    第三步、等一会AS就能识别出来。

    6

    annotationProcessor

    apt已经停止更新,需要全面切换到annotationProcessor,以防止不必要的坑。
    7

    versionName、versionCode

    application项目里面必须得有这两个属性。
    8

    拆分

    建议从原有工程中逐步将功能拆分至各个组件项目,而不是另起一个全新项目。
    9

    Service

    service必须放到application项目中,不能放到library项目中,必须注意!!!
    10

    BuildConfig

    application工程对library工程的依赖都是release依赖!!!

    所以一些根据debug和release来判断的操作,需要放到application工程里面。

    还有一种解决方案:publishNonDefault true

    参考 http://www.jianshu.com/p/64f57439934b

    11

    So文件

    各个工程的libs里面的so文件,需要在各个工程的build.gradle文件中用如下方式引入,不然打包的时候so文件包含不进去:

    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
    }
    }

     

    12

    AsyncTask

    asynctask在组件间调用的时候会出现AsyncTask java.lang.ClassCastException: java.lang.Object[] cannot be cast to java.lang.Void[] 异常。

    解决方案:

    1、去掉泛型;

    2、泛型将Void类型换成非Void类型。

    13

    ApplicationId

    applicaitonId和packageName的区别:

    1、如果没有applicationId,则以packageName的值为应用包名;

    2、如果有applicationId,则以applicationId的值为应用包名;

    应用案例:

    Module模块中,如果需要使用到极光推送的,而极光推送跟包名又是强相关的,

    可以利用applicationId进行包名控制,而不需要去改动packageName。

    14

    JPush

     

    目前项目使用的JPush版本还是1.7.0。

    在module作为单个apk独立运行时,会出现如下情况:

    提示:

    [AndroidUtil] The permissoin is required - android.permission.WRITE_SETTINGS
    [AndroidUtil] You should make main activity extends InstrumentedActivity (JPush), otherwise you will not see user click and user active time start on report in Portal.

    有两种情况:

    (一)原因是这个版本在android api为23及以上使用时,不能够权限更改做判断;

    目前解决方案是将targetSdkVersion设为21及以下。

    但是在app壳工程里面targetSdkVersion设为23是可以的。

     (二)原因是app没有签名。

    在buildTypes里面要加上:signingConfig signingConfigs.debugConfig

    15

    Instant Run

    在Android Studio 2.3.3和Gradle 3.3环境下面,开启instant run后,整个项目的编译和单个组件的编译会异常耗时,而且会出现处理R.class时crash现象;

    所以在平时调测过程中,需要将instant run关闭后编译。

    16

    编码问题

     org.gradle.jvmargs = -Dfile.encoding=UTF-8

    如果jvmargs的设置如上,则会出现项目中png图片不能识别问题:

    AAPT err(Facade for 169869688) : No Delegate set : lost message:\\?\xxx\base-core\build\intermediates\bundles\default\res\drawable-xhdpi-v4\query_loding5.png ERROR: Unable to open PNG file

    17

    resourcePrefix

    设置了resourcePrefix值后,所有的资源名必须以指定的字符串做前缀,否则会报错。
    但是resourcePrefix这个值只能限定xml里面的资源,并不能限定图片资源,所有图片资源仍然需要手动去修改资源名。

    18

    引用aar

    在Android Studio中创建一个module或者导入一个module的时候,如果这个module中依赖了aar库,当build工程的时候,会出现failed to resolve这个错误。

    需要在引用这个module之前的每一个module或app的build.gradle里面,添加如下代码:

     

    1. repositories {  
    2.     flatDir {  
    3.         dirs project(':你的module名称').file('libs')  
    4.     }  
    5. }  

     

    19

    手动替换aar

    需要关闭android studio然后重新打开,不然死活识别不出来。
    20Multiple dex files define Lcom/xx/xx/BuildConfig

    解决方法一:找到引用的aar包,用压缩软件打开,把里面的BuidConfig给删了,然后引用删除后的包

    解决方法二:在library工程的build.gradle中的android范围内加入:packageBuildConfig(false)

    21使用ButterKnife后的混淆

    由于使用了R2这个资源文件,所以在混淆的时候需要增加排除对R2的混淆,如下:

    -keep class **.R$* {*;}
    -keep class **.R2$* {*;}
    22找不到资源文件:NoSuchFieldError

    开发的时候,通过 Ctrl+右键 能够正确找到相应的ResId,但是一旦运行起来,无论是通过ButterKnife还是findViewById都会报此错。此种情况需要检查是否module的layout命名与其他module有冲突,重命名layout文件名称后即可解决。

    建议在不同的module之间配置 gradle:resourcePrefix "xxx_" 加以区分格式

    23ButterKnifemodule工程里面必须引用
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.x.x' 

    不然会出现控件绑定失效,导致OnClick等这样的事件无法实现

    24

    APP+Library

    +productFlavors+buildTypes

    好处:library工程根据app工程传过来的参数进行个性化配置,比如测试环境or正式环境。

    详情参加:http://blog.csdn.net/wenyiqingnianiii/article/details/70183816

    打包注意:

    developCompile project(path: ':library', configuration: 'developDebug')

    1、这样的打包形式,以在app工程的build.gradle脚本为例:

    developCompile的develop表示app的Flavors;configuration的developDebug表示library工程的flavors是develop,buildTypes是debug;

    所以在library中必须有对应的flavors。

    2、app工程向library工程传值

    (1)library可以通过libraryVariants.all、variant.buildType.name、variant.flavorName来判断由app传入的值是什么,从而进行个性化处理。

    (2)当然,library还可以通过直接在buildTypes、productFlavors脚本里面编写代码进行个性化处理。注:publishNonDefault true

    (3)app工程初始化的时候,可以调用library工程的类进行初始化设定。

    3、打包的时候,左下角的Build Variants选择Build Variant的时候,需要对应app脚本中xxxCompile的信息。

    如按照上述脚本,应该选择app:developDebug,library:developDebug。

    同样,在右上角的Gradle脚本里面,也要选择对应的脚本名称,比如这个脚本的名称为:assembleDevelopDebug。

    25library二次引用

    注:一定要以maven的形式compile进来;如果library工程有jar包,app工程要把重复的jar包去掉。

    1、比如A工程引用了B库,B库引用了C库,如果A工程引用了C库,那么C库知会被引用一次,并且是最新版本的。

    如果B库引用的C库是1.0版本,而A工程引用的C库是1.1版本,那么在A工程里面知会引入C库的1.1版本。

    所以不用担心C工程二次引用重复的问题。但如果是jar包则不行。

    2、可以用+号表示永远引用最新版本的库工程,比如compile 'com.midea.smart.lib:lib-ui:+',但不建议这样引用。推荐写成固定的版本。

    原因:

    每次build时会向网络进行检查,国内访问仓库速度很慢;

    库更新后可能会更改内部逻辑而带来bug,动态版本无法通过git的diff来规避此问题;

    每个开发者都可能会得到不同的最新版本,带来潜在隐患。

    3、比如A工程引用了B库,B库引用了C库,如果A工程引用了C库,但是B库引用的C库groupId不一样,

    这样会造成的结果就是,A工程知会引入B库所引用的C库的版本,比如B库引用的C库的版本是2.0,而app工程引用的C库的版本是2.1,

    这样的情况下,app工程只会引入2.0版本的C库,这是一个坑,不过也不是经常遇到。

     

    26Android Studio引用版本号

    android studio的坑,compile的版本号如果以前引用过的话,后面修改后,如果保持版本号不变,android studio再次引用进来会导致一些莫名其妙的问题。

    解决方案:

    按照maven的版本管理规范,后续将maven上面的版本正式管理起来,有变更时版本号往上增加:
    1、平时开发版本放到snapshot上面;
    2、release只用来上传正式发布版本。

    27Maven上传library生成的aar或jar要注意只能生成一个,要门debug要么release,不要两个都一起生成,这样都会传到maven上。
    28工程编译速度慢

    工程编译速度慢,主要跟以下两种情况有关,我们可以针对性地做出一些优化措施:

    1、Flavors+BuildType组合,编译出来的library工程的aar包很多,导致编译速度慢;

    解决措施:确定library是否需要flavors和buildtype,如果不需要,就可以不用用这种组合编译方式编译,可以只选择一个。

    2、settings.gradle中包含的library工程太多,这个影响是致命的。

    解决措施:将library工程的aar包,放到app工程的libs里面,在app里面引用aar。

    29错误: 找不到符号

    app工程引用library工程的时候,有时候会发现“错误: 找不到符号”这个错误,但是跳转到代码处有没有报错。

    实际上这个原因是因为library工程中将混淆开启了,所以需要将library的minifyEnabled设置为false!不能用混淆!

    展开全文
  • Android组件化开发

    2019-12-23 17:26:56
    教你打造一个Android组件化开发框架 ???? CC:Component Caller,一个android组件化开发框架, 已开源。 github地址: https://github.com/luckybilly/CC 本文主要讲解框架实现原理,如果只是想了解一下如何使用...
  • Android业务组件化开发实践
  • Android 组件化开发

    2018-03-13 16:13:01
    前言最近自己学习了一下组件化,然后参考各位大神的一些知识点,然后自己总结了比较简单化的文档,其实组件化还有很多的地方需要去深入学习的,后面自己再去慢慢补充学习。这里有哪里存在不足,可以完善的,希望大家...
  • 组件化开发的时候,会面临的一个问题就是组件的调试。 即组件和主工程不在同一个工程目录下,主工程对组件的依赖,是通过依赖组件发布的aar包的方式引入。当组件开发了新的功能,就会发布一个新的 aar 包,并在主...
  • 组件化开发基础

    2019-03-24 17:56:52
    一、组件化基础 1.1、组件化与模块化区别 模块:模块指的是独立的业务模块,比如首页模块、商城模块等。 组件:组件指的是单一的功能组件,如 登录组件、支付组件等,每个组件都可以以一个单独的 module 开发。...
  • 正在做个项目,是由传统项目转为组件化开发的,由于前期对项目评估不到位,才导致这次的改动,项目已经开发了一些功能,所以在像组件化开发模式转的时候,还是有一些工作量的。所以在项目评估前期还是要评估准确些。...
  • 教你打造一个Android组件化开发框架

    万次阅读 2017-12-03 23:21:51
    无需注解,支持任意功能调用&回调的android组件化开发框架。兼容同步&异步调用及同步&异步实现,并做到调用方式和实现方式解耦。
  • 转自:《Android业务组件化开发实践》 借用阿布倪盟博的一句话:“在MDCC中冯森林老师的《回归初心,从容器化到组件化》,为我们这些没有那么多精力折腾黑科技开发者们打开了另一扇门” 。 组件化并不是...
  • 组件化开发中ARouter的坑

    千次阅读 2019-03-04 13:17:22
    可能的原因: ...这就导致aar里的类名跟最后一体那个项目自己的类重名冲突了。 解决办法:修改每个项目默认的模块名(app)为单独的,如app_a,app_b之类的,避免生成的ARouter类名字一样即可
  • 组件化开发总体展示什么是组件化 基于组件的软件工程(CBSE),也称为基于组件的开发(CBD),是软件工程的一个分支 在整个给定的软件系统中,对整个系统中的各个功能模块进行分离,每个模块都是一个Module,都是可单独...
  • Android模块化和组件化开发

    千次阅读 2019-07-24 08:59:30
    1.2:模块化和组件化的区别 1.3:模块化的优点 1.4:模块化的层级介绍 二.如何实现组件化 2.1:实现模块化需要解决的问题 2.2:各个问题的解决方法 一:模块化介绍 (1)对于简单的小项目,大多都采用的是...
  • 该demo用了组件化 为什么要组件化 近年来,为什么这么多团队要进行组件化实践呢?组件化究竟能给我们的工程、代码带来什么好处?我们认为组件化能够带来两个最大的好处: 提高组件复用性 可能有些人会觉得,提高...
  • 1.为什么要组件化 1.1 为什么要组件化 1.2 现阶段遇到的问题 2.组件化的概念 2.1 什么是组件化 2.2 区分模块化与组件化 2.3 组件化优势好处 2.4 区分组件化和插件化 2.5 application和library 3.创建组件化...
  • 1.为什么要组件化 1.1 为什么要组件化 1.2 现阶段遇到的问题 2.组件化的概念 2.1 什么是组件化 2.2 区分模块化与组件化 2.3 组件化优势好处 2.4 区分组件化和插件化 2.5 application和library 3.创建组件化...
  • 名词解释 模块化:模块是APP的组成部分,所有的模块组装起来便是一个完整的APP 组件化:使模块能够单独运行为组件化二.模块化与组件化的差别 (1) 类型不同 模块:com.android.libray 组件:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,267
精华内容 906
关键字:

aar组件化开发