Android 组件化集成坑及合并AndroidManifest.xml 的问题

问题一

主APP里面报错:

tools:replace specified at line: for attribute android:appComponentFactory, but no new value specified main manifest (this file), line

    Attribute application@appComponentFactory value=(androidx.core.app.CoreComponentFactory) from [androidx.core:core:1.3.1] AndroidManifest.xml:24:18-86
    is also present at [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91 value=(android.support.v4.app.CoreComponentFactory).
    Suggestion: add 'tools:replace="android:appComponentFactory"' to <application> element at AndroidManifest.xml:9:5-24:19 to override.

按照提示添加,

tools:replace="android:appComponentFactory"

仍然报错,

> Task :app:processDebugMainManifest FAILED
[androidx.versionedparcelable:versionedparcelable:1.1.0] C:\Users\username\.gradle\caches\transforms-2\files-2.1\ee32a41b299ebcf4e78d691344f52243\versionedparcelable-1.1.0\AndroidManifest.xml Warning:
    Package name 'androidx.versionedparcelable' used in: androidx.versionedparcelable:versionedparcelable:1.1.0, com.android.support:versionedparcelable:28.0.0.
H:\Android\practice\QQ\app\src\main\AndroidManifest.xml:9:5-25:19 Error:
    tools:replace specified at line:9 for attribute android:appComponentFactory, but no new value specified
H:\Android\practice\QQ\app\src\main\AndroidManifest.xml Error:
    Validation failed, exiting

最后在APP里面的清单文件加入,不用再别的module里面添加

 android:appComponentFactory="renyizifu任意字符,不能为空,仍然报错,但是不影响运行"
 tools:replace="android:appComponentFactory"
2021-11-23 19:02:20.045 14285-14285/com.cc.qq E/LoadedApk: Unable to instantiate appComponentFactory
    java.lang.ClassNotFoundException: Didn't find class "com.cc.qq.AppComponentFactory" on path: DexPathList[[zip file "/data/app/com.cc.qq-VXr3KxaFWBhe82itimOPVA==/base.apk"],nativeLibraryDirectories=[/data/app/com.cc.qq-VXr3KxaFWBhe82itimOPVA==/lib/arm64, /system/lib64, /hw_product/lib64, /system/product/lib64]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:209)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
        at android.app.LoadedApk.createAppFactory(LoadedApk.java:270)
        at android.app.LoadedApk.createOrUpdateClassLoaderLocked(LoadedApk.java:1005)
        at android.app.LoadedApk.getClassLoader(LoadedApk.java:1129)
        at android.app.LoadedApk.getResources(LoadedApk.java:1419)
        at android.app.ContextImpl.createAppContext(ContextImpl.java:2662)
        at android.app.ContextImpl.createAppContext(ContextImpl.java:2644)

继续报错

Duplicate class android.support.v4.app.INotificationSideChannel found 
in modules core-1.3.1-runtime (androidx.core:core:1.3.1)
 and support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0)
Duplicate class android.support.v4.app.INotificationSideChannel found in modules core-1.3.1-runtime (androidx.core:core:1.3.1) and support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0)


Duplicate class android.support.v4.app.INotificationSideChannel$Stub found in modules core-1.3.1-runtime (androidx.core:core:1.3.1) and support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0)
Duplicate class android.support.v4.app.INotificationSideChannel$Stub$Proxy found in modules core-1.3.1-runtime (androidx.core:core:1.3.1) and support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0)
Duplicate class android.support.v4.graphics.drawable.IconCompatParc
....
Duplicate class androidx.core.graphics.drawable.IconCompatParcelizer found in modules core-1.3.1-runtime (androidx.core:core:1.3.1) and support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0)
Duplicate class androidx.core.internal.package-info found in modules core-1.3.1-runtime (androidx.core:core:1.3.1) and support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0)
Duplicate class androidx.versionedparcelable.CustomVersionedParcelable found in modules versionedparcelable-1.1.0-runtime (androidx.versionedparcelable:versionedparcelable:1.1.0) and versionedparcelable-28.0.0-runtime (com.android.support:versionedparcelable:28.0.0)
Duplicate class androidx.versionedparcelable

* What went wrong:
Execution failed for task ':app:mergeDebugJavaResource'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.MergeJavaResWorkAction
   > 2 files found with path 'META-INF/androidx.cursoradapter_cursoradapter.version'.
     Adding a packagingOptions block may help, please refer to
     https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.PackagingOptions.html

....

解决方案:根目录下的gradle.properties添加

# 这是因为混合支持库。通过添加这些行选择androidX作为您的支持库
android.useAndroidX=true
#上面一句默认存在,添加下面一句
android.enableJetifier=true

总的添加代码为

android.useAndroidX=true
# 这是因为混合支持库。通过添加这些行选择androidX作为您的支持库
android.enableJetifier=true

 android:appComponentFactory="任意字符"
 tools:replace="android:appComponentFactory"
    <application
        android:name=".App"
        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/Theme.QQ"
        android:appComponentFactory="任意字符x"
        tools:replace="android:appComponentFactory">

组件化注意事项

一、commonLib包中引入第三方的库为api 而非implementation,不然Module引入调用不到该库依赖

    implementation 'androidx.appcompat:appcompat:1.2.0'

    // 替换成最新版本, 需要注意的是api
    api 'com.alibaba:arouter-api:1.5.2'
    annotationProcessor 'com.alibaba:arouter-compiler:1.5.2'

    api "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"
    // optional - RxJava2 support for Room
    api "androidx.room:room-rxjava2:$room_version"
    // optional - RxJava3 support for Room
    api "androidx.room:room-rxjava3:$room_version"

二、组件化里面的字module处理事项

1、组件里面的module里面需要合并AndroidManifest.xml资源、android 目录下,跟defaultConfig 同级
2、判断是否为发布模式变更application和Library,跟android节点同级,根目录
3、判断是否为发布模式变更是否有applicationID等,android-defaultConfig 节点下
4、有自定义处理器需要添加选项配置参数defaultConfig 节点
比如order中
if (isRelease) {
// 如果是发布版本时,各个模块都不能独立运行
    apply plugin: 'com.android.library'
} else {
    apply plugin: 'com.android.application'
}
android {
    ...
    defaultConfig {
      ....
        if (!isRelease) {
            //  如果是集成化模式,不能有applicationId组件化模式能独立运行才能有applicationId
            applicationId "com.cc.order"
       }       

    
        // 这个方法接收三个非空的参数,第一个:确定值的类型,第二个:指定key的名字,第三个:传值(必须是String)
        // 为什么需要定义这个?因为src代码中有可能需要用到跨模块交互,如果是组件化模块显然不行
        // 切记:不能在android根节点,只能在defaultConfig或buildTypes节点下
        buildConfigField("boolean", "isRelease", String.valueOf(isRelease))

        // 在gradle文件中配置选项参数值(用于APT传参接收)
        // 切记:必须写在defaultConfig节点下
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [moduleName: project.getName(), packageNameForAPT: packageNameForAPT]
            }
        }
     // 配置资源路径,方便测试环境,打包不集成到正式环境
    sourceSets {
        main {
            if (!isRelease) {
                // 如果是组件化模式,需要单独运行时
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                // 集成化模式,整个项目打包apk
                manifest.srcFile 'src/main/AndroidManifest.xml'
                java {
                    // release 时 debug 目录下文件不需要合并到主工程
                    exclude '**/debug/**'
                }
            }
        }
    }
}

三、清单文件合并子Module中在modulename->src->main->下创建debug文件,跟java同级,复制AndroidManifest.xml到debug目录中。

image.png

四、AutoService、SPI机制的resource、跨进程通信的aidl、清单文件合并的debug文件都在src->main目录下

image.png

三、集成的问题

1、各个module的布局一定不能名字重复

2、各个module的path路径一定要注意不能重复

3、初始化ARouter的时候看看打印日志if环境,不然AROuter日志不打印

转换异常,但是导包正常,一般是布局名字重复,更改布局名字

2021-11-24 01:05:32.922 3684-3684/com.cc.qq E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.cc.qq, PID: 3684
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.cc.qq/com.cc.personnal.MainActivity}: java.lang.ClassCastException: com.cc.qq.databinding.ActivityMainBindingImpl cannot be cast to com.cc.personnal.databinding.ActivityMainBinding
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4060)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4247)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:91)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2613)
        at android.os.Handler.dispatchMessage(Handler.java:110)
        at android.os.Looper.loop(Looper.java:219)
        at android.app.ActivityThread.main(ActivityThread.java:8668)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)
     Caused by: java.lang.ClassCastException: com.cc.qq.databinding.ActivityMainBindingImpl cannot be cast to com.cc.personnal.databinding.ActivityMainBinding
        at com.cc.personnal.MainActivity.onCreate(MainActivity.java:21)
        at android.app.Activity.performCreate(Activity.java:8214)
        at android.app.Activity.performCreate(Activity.java:8202)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1320)

各个module的path路径一定要注意不能重复,不匹配的情况,写成常量

package com.cc.common.arouter;

public class RouterPath {
    public static final String APP_GROUP="app";
    public static final String ORDER_GROUP="order";
    public static final String PERSONAL_GROUP="personal";


    //app
    public static final String ROUT_APP_MainActivity="/app/MainActivity";

    //order
    public static final String ROUT_ORDER_MainActivity="/order/MainActivity";

    //personal
    public static final String ROUT_PERSONAL_MainActivity="/pesonal/MainActivity";

}

3、注意初始化的BuildConfig不要弄错了,没有日志证明if为false

   // 这两行必须写在init之前,否则这些配置在init过程中将无效
        if (BuildConfig.DEBUG) {
            // 打印日志
            ARouter.openLog();
            // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
            ARouter.openDebug();
        }
        // 尽可能早,推荐在Application中初始化
        ARouter.init(this);

四、注解处理器的问题,每个gradle文件下要添加注解处理器的生成目录

android{
  ...
  defaultConfig{
   javaCompileOptions {
            annotationProcessorOptions {
                arguments = [AROUTER_MODULE_NAME: project.getName()]
            }
        }
  }
}

五、注解处理器dependencies下的依赖问题

1、commonLibrary依赖ARouter:api,透传

2、AppModule、OrderModule、PersonalModule依赖commonLibrary:implementation

3、AppModule依赖OrderModule、PersonalModule:implementation

4、AppModule依赖了OrderModule、PersonalModule,可不依赖commonLirabry,那AppModule依赖了OrderModule、PersonalModule改为api

五的点有问题验证,dependencies中最好都加上

 implementation project(':common') // 公共基础库

    implementation 'com.alibaba:arouter-api:1.5.2'
    annotationProcessor 'com.alibaba:arouter-compiler:1.5.2'
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容