Android support和Androidx库不能共存问题

2019-11-26 03:49:40

参考地址 Android support和Androidx库不能共存问题

一、问题描述

今天升级了android studio3.4.1,导入以前的一个旧项目,并且升级了lottie-android动画库到最新版本3.0.3,编译发现出现如下报错:


Manifest merger failed : Attribute application@appComponentFactory value=(android.support.v4.app.CoreComponentFactory) from [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91

is also present at [androidx.core:core:1.0.0] AndroidManifest.xml:22:18-86 value=(androidx.core.app.CoreComponentFactory).

Suggestion: add 'tools:replace="android:appComponentFactory"' to <application> element at AndroidManifest.xml:5:5-20:19 to override.


1

2

3

4

于是按照报错日志提示,在AndroidManifest.xml的application中添加tools:replace="android:appComponentFactory",如下所示:


<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"

      tools:ignore="AllowBackup,GoogleAppIndexingWarning"

      tools:replace="android:appComponentFactory">

1

2

3

4

5

6

7

8

9

然后编译继续报错如下:


Caused by: org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:processDebugManifest'.

at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:95)

at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:91)

at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:57)

at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:119)

at org.gradle.api.internal.tasks.execution.ResolvePreviousStateExecuter.execute(ResolvePreviousStateExecuter.java:43)

at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:93)

at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:45)

at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:94)

at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:56)

at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:55)

at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)

at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:67)

at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)

at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:49)

at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:315)

at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:305)

at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)

at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:101)

at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)

at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:49)

at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:43)

at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:355)

at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:343)

at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:336)

at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:322)

at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:134)

at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:129)

at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:202)

at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:193)

at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:129)

... 6 more

Caused by: java.lang.RuntimeException: Manifest merger failed with multiple errors, see logs

at com.android.builder.core.AndroidBuilder.mergeManifestsForApplication(AndroidBuilder.java:558)

at com.android.build.gradle.tasks.ProcessApplicationManifest.doFullTaskAction(ProcessApplicationManifest.java:208)

at com.android.build.gradle.internal.tasks.IncrementalTask.taskAction(IncrementalTask.java:106)

at sun.reflect.GeneratedMethodAccessor849.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:498)

at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)

at org.gradle.api.internal.project.taskfactory.IncrementalTaskAction.doExecute(IncrementalTaskAction.java:47)

at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:41)

at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28)

at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$2.run(ExecuteActionsTaskExecuter.java:284)

at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)

at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)

at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)

at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)

at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)

at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:273)

at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:258)

at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$200(ExecuteActionsTaskExecuter.java:67)

at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:145)

at org.gradle.internal.execution.impl.steps.ExecuteStep.execute(ExecuteStep.java:49)

at org.gradle.internal.execution.impl.steps.CancelExecutionStep.execute(CancelExecutionStep.java:34)

at org.gradle.internal.execution.impl.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:69)

at org.gradle.internal.execution.impl.steps.TimeoutStep.execute(TimeoutStep.java:49)

at org.gradle.internal.execution.impl.steps.CatchExceptionStep.execute(CatchExceptionStep.java:33)

at org.gradle.internal.execution.impl.steps.CreateOutputsStep.execute(CreateOutputsStep.java:50)

at org.gradle.internal.execution.impl.steps.SnapshotOutputStep.execute(SnapshotOutputStep.java:43)

at org.gradle.internal.execution.impl.steps.SnapshotOutputStep.execute(SnapshotOutputStep.java:29)

at org.gradle.internal.execution.impl.steps.CacheStep.executeWithoutCache(CacheStep.java:134)

at org.gradle.internal.execution.impl.steps.CacheStep.lambda$execute$3(CacheStep.java:83)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

通过查看日志知道这是AndroidManifest中的报错,然后到AndroidManifest.xml的Merged Manifest中查看报错信息为:


Merging Errors: 

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

Error: Validation failed, exiting app main manifest (this file)

1

2

3

上面所说的意思就是,我们没有给android:appComponentFactory指定新的值,所以在application中继续添加android:appComponentFactory="android.support.v4.app.CoreComponentFactory",如下:


<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"

      tools:ignore="AllowBackup,GoogleAppIndexingWarning"

      tools:replace="android:appComponentFactory"

      android:appComponentFactory="android.support.v4.app.CoreComponentFactory">

1

2

3

4

5

6

7

8

9

10

结果编译又出现报错,如下:


Caused by: com.android.ide.common.workers.WorkerExecutorException: 1 exception was raised by workers:

java.lang.RuntimeException: Duplicate class android.support.v4.app.INotificationSideChannel found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)

Duplicate class android.support.v4.app.INotificationSideChannel$Stub found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)

Duplicate class android.support.v4.app.INotificationSideChannel$Stub$Proxy found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)

Duplicate class android.support.v4.graphics.drawable.IconCompatParcelizer found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)

Duplicate class android.support.v4.os.IResultReceiver found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)

Duplicate class android.support.v4.os.IResultReceiver$Stub found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)

Duplicate class android.support.v4.os.IResultReceiver$Stub$Proxy found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)

Duplicate class android.support.v4.os.ResultReceiver found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)

Duplicate class android.support.v4.os.ResultReceiver$1 found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)

Duplicate class android.support.v4.os.ResultReceiver$MyResultReceiver found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)

Duplicate class android.support.v4.os.ResultReceiver$MyRunnable found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)

Duplicate class androidx.core.graphics.drawable.IconCompatParcelizer found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)

Duplicate class androidx.core.internal.package-info found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)

Duplicate class androidx.versionedparcelable.CustomVersionedParcelable found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)

Duplicate class androidx.versionedparcelable.NonParcelField found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)

Duplicate class androidx.versionedparcelable.ParcelField found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)

Duplicate class androidx.versionedparcelable.ParcelImpl found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)

Duplicate class androidx.versionedparcelable.ParcelImpl$1 found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)

Duplicate class androidx.versionedparcelable.ParcelUtils found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)

Duplicate class androidx.versionedparcelable.VersionedParcel found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)

Duplicate class androidx.versionedparcelable.VersionedParcel$1 found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)

Duplicate class androidx.versionedparcelable.VersionedParcel$ParcelException found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)

Duplicate class androidx.versionedparcelable.VersionedParcelParcel found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)

Duplicate class androidx.versionedparcelable.VersionedParcelStream found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)

Duplicate class androidx.versionedparcelable.VersionedParcelStream$FieldBuffer found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)

Duplicate class androidx.versionedparcelable.VersionedParcelStream$InputBuffer found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)

Duplicate class androidx.versionedparcelable.VersionedParcelable found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)

Duplicate class androidx.versionedparcelable.VersionedParcelize found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

从日志中可以看出,这是因为Android support和Androidx库不能共存引起的编译报错。因为最新的lottie-android动画库已经使用了Androidx库,而我的项目使用的还是Android support库,从而引起的冲突。因此解决办法有两种。


二、解决办法

方法一:将Android support库转换为Androidx库

(1)将build tools更新到3.4.1,如下:


dependencies {

    classpath 'com.android.tools.build:gradle:3.4.1'

}

1

2

3

gradle更新到5.1.1,如下:


distributionBase=GRADLE_USER_HOME

distributionPath=wrapper/dists

zipStoreBase=GRADLE_USER_HOME

zipStorePath=wrapper/dists

distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip

1

2

3

4

5

依赖库统一更新到28.0.0,如下:


dependencies {

    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

    implementation 'com.android.support:appcompat-v7:28.0.0'

    implementation 'com.airbnb.android:lottie:3.0.3'

}

1

2

3

4

5

6

这一步非常重要,不然会导致第二步转换不成功。


(2)完成(1)之后,右键工程→Refactor→Migrate to AndroidX…,如下图所示:


(3)选中所有需要重命名的目录,点击Do Refactor,如下图所示:


(4)执行上面的步骤之后,发现Android support库已经被全部替换成了Androidx库了,至此项目已经可以成功的运行了。


方法二:将Androidx库转换为Android support库

前面已经说过了,这个问题是由于升级了lottie-android动画库到最新版本引起的,所以我们只需要将lottie-android动画库的版本降低到它使用Android support库的版本就可以了,其他的第三方库也是同样的解决方法,但是由于后续会更新升级第三方库,所以不推荐使用此方案解决这个问题,推荐使用方法一解决这样的报错问题。



  • 2020-12-07 15:04:03

    node开发邮件系统总结

    因为multipart这种形式比较复杂,因此要利用boundary分割符,将邮件体分割成不同段来进行解析,boundary分为父段和子段,父段一般出现0次或1次,出现在末尾,每个子段中也有content-type和boundary,需要在进行解析,如果遇到i,iii里面的情况可直接解析,如果遇到ii中的情况,再按ii中的步骤进行解析

  • 2020-12-07 15:17:45

    email-templates + mjml 发送邮件

    mjml 是一个很不错的响应式邮件html 内容标签库,email-templates 是一个灵活强大的邮件发送框架,两者集成起来我们 可以设计灵活强大的邮件发送系统,以下是一个简单的集成使用,实际使用还有好多地方需要完善

  • 2020-12-07 15:19:00

    响应式邮件的编写插件介绍mjml

    以前做项目碰到发邮件的需求,邮件模板的编辑就是一件头疼的事。因为虽说邮件是支持 HTML 的,但是确是 HTML 子集程度的支持,所以存在必须通过 <table> 排版的恶心之处,还有很多兼容性的坑。本质上是各家邮件商的标准有差异吧。

  • 2020-12-07 16:14:22

    nodejs队列实现amqplib,rabbitmq

    其中StartConsumer 会在项目启动时启动,在整个生命周期中一直保持监听状态,在程序结束时mq的链接关闭。需要注意的是 noAck 这个参数,当为false是表示消息出队后不会自动删除,如果设置成true,则无论消息处理成功与否此消息会被删除。注意到在消息不成功是,调用了ch.nack(msg)),此方法是将消息重新入队。

  • 2020-12-07 16:15:46

    RabbitMQ详解

    当前市面上mq的产品很多,比如RabbitMQ、Kafka、ActiveMQ、ZeroMQ和阿里巴巴捐献给Apache的RocketMQ。甚至连redis这种NoSQL都支持MQ的功能。 ActiveMQ ActiveMQ是apache出品,最流行的,能力强劲的开源消息总线,并且它一个完全支持JMS规范的消息中间件。其丰富的API、多种集群构建模式使得它成为业界老牌消息中间件,在中小型企业中应用广泛。

  • 2020-12-07 16:17:53

    nodejs用redis实现队列操作

    其实nodejs实现队列的方式又很多中,也有很多开源的插件和队列数据库可以使用,但是呢,如果我们一个简单的项目,完全可以使用redis来实现队列, 这样再不增加技术难度的同事,我们也就可以完美的实现一个队列

  • 2020-12-07 22:02:44

    intellij idea远程开发的几个想法

    我之前是用idea上面自带的stfp来做的本地开发同步到linux服务器编译,但是我发现这个如果多个客户端同时开发,或者多个同事一起开发,服务器上的就不能更新到本地。是不能增量更新到本地,必须全部下载,比对下载也行,但是工程量打了就特别慢。