Android -- AndroidX库

前言

今天在 Android Studio 上新建了个项目,引入 butterknife:10.0.0,运行后居然抛出了异常:

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-19:19 to override.

按照日志提示
在 AndroidManifest.xml 中添加
tools:replace=“android:appComponentFactory”

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

    <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:replace="android:appComponentFactory">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

运行后,仍抛出异常:

Manifest merger failed with multiple errors, see logs

显示 AndroidManifest.xml 文件里出错
查看 AndroidManifest.xml 文件里的 Merged Manifest:
在这里插入图片描述
折腾几番后,仍找不到解决方法,就直接上 butterknife 的 issue 上寻找答案。
在这里插入图片描述
发现 butterknife:10.0.0 已经不支持 support 老版库,如果需要使用,只能使用9.0.0这版。 butterknife:10.0.0 只支持新的 AndroidX 库。

ButterKnife的github地址
Github: https://github.com/JakeWharton/butterknife

1. AndroidX库

Google 2018 IO 大会推出了 Android 新的扩展库 AndroidX,用于替换原来的 Android support 扩展库,将原来的 android.替换成 androidx.;只有包名和 Maven 工件名受到影响,原来的类名,方法名和字段名不会更改。

1.1 AndroidX变化
1、常用依赖库对比
Old build artifactAndroidX build artifact
com.android.support:appcompat-v7:28.0.2androidx.appcompat:appcompat:1.0.0
com.android.support:design:28.0.2com.google.android.material:material:1.0.0
com.android.support:support-v4:28.0.2androidx.legacy:legacy-support-v4:1.0.0
com.android.support:recyclerview-v7:28.0.2androidx.recyclerview:recyclerview:1.0.0
com.android.support.constraint:constraint-layout:1.1.2androidx.constraintlayout:constraintlayout:1.1.2
2、常用支持库类对比
Support Library classAndroidX class
android.support.v4.app.Fragmentandroidx.fragment.app.Fragment
android.support.v4.app.FragmentActivityandroidx.fragment.app.FragmentActivity
android.support.v7.app.AppCompatActivityandroidx.appcompat.app.AppCompatActivity
android.support.v7.app.ActionBarandroidx.appcompat.app.ActionBar
android.support.v7.widget.RecyclerViewandroidx.recyclerview.widget.RecyclerView

更多详细变化内容,可查看官方文档

AndroidX了解一下

2. 解决第三方库只支持 AndroidX 库问题

2.1 方法一:将项目的 support 库统一转换成 AndroidX 库
1、AS 更新升级配置
  • 将 AS 更新至 AS 3.2 及以上
  • Gradle 插件版本改为 4.6 及以上,gradle 版本至少为3.2.0以上
    在这里插入图片描述
    在这里插入图片描述
  • compileSdkVersion 版本升级到 28及以上
    在这里插入图片描述
  • buildToolsVersion 版本改为 28.0.2及以上
2、开始迁移AndroidX
方法一:一键迁移AndroidX库

在 AS 3.2 Canary 中添加了一键迁移的功能,Refactor -> Migrate to AndroidX 。
在这里插入图片描述
选择Migrate
在这里插入图片描述
选择要转换的项目
在这里插入图片描述
选择需要转换为 AndroidX 包的库,点击 Do Refactor
在这里插入图片描述

方法二:配置 gradle.properties 迁移AndroidX库

除了 Do Refactor 方法外,还可以通过配置 gradle.properties 引入 AndroidX 库。

android.useAndroidX=true
android.enableJetifier=true

其中:

  • android.useAndroidX=true 表示当前项目启用 AndroidX
  • android.enableJetifier=true 表示将依赖包也迁移到 AndroidX 。如果取值为 false ,表示不迁移依赖包到 AndroidX,但在使用依赖包中的内容时可能会出现问题。当然了,如果你的项目中没有使用任何三方依赖,那么,此项可以设置为false

在使用 android.enableJetifier=false 时,需要注意:
引入某些第三方的最新库时,如 butterknife:10.0.0,是只支持新的 AndroidX 库,所以要将整个项目的依赖都转换为 AndroidX,否则编译就会报错。

3、对比 Android support 库和 AndroidX 库

转换前和转换后类库对比
Android support 库
在这里插入图片描述
AndroidX 库
在这里插入图片描述

4、androidx.constraintlayout.widget.ConstraintLayou 异常

当将所有库的依赖都转换为 AndroidX 后,运行项目,居然抛出 androidx.constraintlayout.widget.ConstraintLayout 的错误:
在这里插入图片描述
附上 build.gradle 文件和布局 xml 文件
build.gradle

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.0-alpha4'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-alpha4'
}

布局 xml 文件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

所有的 support 库都已改成 AndroidX 了,而且布局中 ConstraintLayout 控件的引入也改成了 androidx,为什么还会抛出 Error inflating class androidx.constraintlayout.widget.ConstraintLayout 异常??

解法:
原来是 androidx.constraintlayout:constraintlayout:1.1.2 中的一个bug,将

implementation 'androidx.constraintlayout:constraintlayout:1.1.2'

改成

implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

编译后,即可成功运行出来。

2.2 方法二:降低第三方库的版本,使其兼容 Android support 库

使用第三方依赖库时,如果最新版本适配的是 AndroidX 库,可降低第三方的库的版本。
如 butterknife,从 butterknife 的 issue 上可知,butterknife:9.0.0 是适配 Android support 库的,如果你的项目仍想使用 Android support 老库,引入 butterknife:9.0.0 即可。

PS:

依赖库的时候,尽量不要使用 latest.release,而使用具体的版本。
原因:

  1. 不会因为依赖库更新,引起兼容问题
  2. 减少每次去检查最新版本,可以节省编译时间

3. 引入 butterknife:10.0.0

在整个项目转换为 AndroidX 库后,引入 butterknife:10.0.0
在 build.gradle 里添加 butterknife:10.0.0

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.testdemo1"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        //AndroidStudio 3.0 canary 8 Annotation processors must be exp
        //添加部分
        javaCompileOptions {
            annotationProcessorOptions {
                includeCompileClasspath true
            }
        }
    }
   .......
}

dependencies {
   ......
    implementation 'com.jakewharton:butterknife:10.0.0'
    implementation 'com.jakewharton:butterknife-compiler:10.0.0'
}

添加后,运行,抛出异常:

Error: Static interface methods are only supported starting with Android N (--min-api 24): void butterknife.Unbinder.lambda$static$0()

原因分析: java8才支持静态接口方法,Android N 要求 jdk 版本为1.8
解决方案:定义和调用静态接口方法的 module 编译时都使用 jdk1.8 即可

原来 butterknife:10.0.0 需要指定 java的 jdk 版本
在 app 的 build.gradle 中添加如下:

android {
     ......
    // 指定jdk版本
    compileOptions {
        sourceCompatibility 1.8
        targetCompatibility 1.8
    }
}

编译后,即可成功运行出来。

4. 总结

AndroidX 虽然目前对我们没有多大的影响,我们可以不使用它,仍然使用旧版本支持库,毕竟没有强制,但从长远来看还是有好处的。AndroidX 重新设计了包结构,旨在鼓励库的小型化,支持库和架构组件包的名字也都简化了,而且也是减轻Android生态系统碎片化的有效方式。之后Android 的一些新的特性,也都会被写在 AndroidX 库中。

5. 附

如果在老版本转换到 AndroidX 的过程中遇到 Program type already present 报错,可参考这个连接,使用androidx时Program type already present报错的一种解决尝试

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值