體驗一下:AndroidX


  • 背景

今天在更新 ButterKnife 到最新版本的時候出現了一個問題,我引入的是 10.1.0 最新版本:

 implementation 'com.jakewharton:butterknife:10.1.0'
 annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.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"

但是添加了上面代碼之后呢,又給你報了一個錯誤:

Manifest merger failed with multiple errors, see logs

 

於是搜索了一下,光有這一行代碼還不夠,必須還要添加一行,代碼如下:

android:appComponentFactory="jasfljapsjpasf" ,這里填入任意字符串即可。

然后又報了這個錯誤,提示你說 api 的等級必須要在24及以上

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

所以你將 api 更改到 24 即可,操作位置如下圖:

體驗一下:AndroidX

 

然后再 sync 一下、或者 rebuild 一下項目就不會報錯了。

更大的坑

你以為這樣就可以運行了嗎?不可能!

比如你在 Activity 中綁定控件的時候,又會報錯:

Error: Invoke-customs are only supported starting with Android O (--min-api 26)

這個簡單,好吧,我就把 api 改到 26 吧,然后在 sync 一下,它又給來了一個錯誤:

More than one file was found with OS independent path 'META-INF/androidx.core_core.version'

這個錯誤說你的 META-INF 目錄下沒有 androidx.core_core.version 這個東西,這個是什么東西?沒見過啊,在下文我會再介紹這個 androidx,現在要緊的是解決這個問題,搜索了一下,只需在 gradle.properties 文件中加入兩行代碼即可:

android.useAndroidX=true
android.enableJetifier=true

具體位置是在 gradle.properties ,如圖:

體驗一下:AndroidX

 

然后在 sync 一下,這樣沒有任何錯誤了。然后在 activity 中會報 :

 

那我就測試一下能否綁定 button 點擊事件吧,不幸的是這里報了一個更大的錯誤:

java.lang.BootstrapMethodError: Exception from call site #1 bootstrap method

at butterknife.internal.DebouncingOnClickListener.<clinit>(DebouncingOnClickListener.java:12)

at com.xww.myapplication2.MainActivity_ViewBinding.<init>(MainActivity_ViewBinding.java:34)

at java.lang.reflect.Constructor.newInstance0(Native Method)

at java.lang.reflect.Constructor.newInstance(Constructor.java:343)

at butterknife.ButterKnife.bind(ButterKnife.java:170)

at butterknife.ButterKnife.bind(ButterKnife.java:99)

at com.xww.myapplication2.MainActivity.onCreate(MainActivity.java:27)

at android.app.Activity.performCreate(Activity.java:7136)

at android.app.Activity.performCreate(Activity.java:7127)

at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)

at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)

at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)

at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)

at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)

at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)

at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)

at android.os.Handler.dispatchMessage(Handler.java:106)

at android.os.Looper.loop(Looper.java:193)

at android.app.ActivityThread.main(ActivityThread.java:6669)

at java.lang.reflect.Method.invoke(Native Method)

at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

原因是:Caused by: java.lang.ClassCastException: Bootstrap method returned null

看我們在 Activity 中綁定事件的代碼:

 @OnClick(R.id.btn)
void onShow() {
Toast.makeText(this, "ddd", Toast.LENGTH_SHORT).show();
}

問題是出在 @OnClick() 這個注解上,將這個注解刪除或者替換成如下代碼:

 btn.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 Toast.makeText(MainActivity.this, "ddd", Toast.LENGTH_SHORT).show();
 }
 });

 

目前還沒有找到解決方法,但是用這種非注解的方式去設置監聽事件也失去了 butterknife 的意義了。所以呢,我們只能回退到 9.0 之前的版本了。搜索了半天,沒有一個可以解決的辦法,但是這個產生這個問題的原因倒是已經明了,想必你也想知道為什么會出現這么多錯誤,下面我們來看看原因。

AndroidX庫

android.useAndroidX=true
android.enableJetifier=true

 

第一行,表示我們在項目中啟用 androidx 這個庫依賴,這就表示我們可以使用 androidx 庫里的所有 api 了,那么到底什么是 androidx 呢?我們就得了解一下。

androidx 是 google 最新推出一種新的軟件包結構,我們都知道 android.support 包,在 api28 之后的項目中,會將 android.support 全部替換為 androidx 包,也就是說我們之后開發都會使用或者慢慢的將項目過渡到這個版本上,而 google 也做出說明,會繼續提供 api27 之前的 android support 包的支持和更新。

但是,google 還會將一些新的特性加入到 androidx 包中,但不會對 android support 包進行添加新特性,可見 google 只是給了我們一些過渡時間,在未來的日子里開發者都會陸續的更新到 androidx 包,那樣 google 也沒有必要對 support 進行維護了。

google 表示 support 包越來越臃腫,而且隨着 api 版本的更新迭代,support 包也越發的令人難以通讀。所以這才推出了 androidx 包,androidx 包將從 1.0 版本開始。

第二行,表示我們當前項目中如果有用到 androidx 包的話,就必須設置為 ture ,否者第三方庫(比如:butterknife)就引入失敗。之所以最新版本的 butterknife 需要 androidx 的支持,是因為 butterknife 的作者在其中添加了 androidx 包的支持,那種種錯誤的原因是因為:amdroidx 與 support 包兩者無法共存,只能使用其中一種。

所以,以上我遭受的種種錯誤的原因就是這個 androidx 包導致的。當然了,軟件更新是一件好事,我們可以體驗最新的技術支持,蛋疼的是在項目中的第三方庫都要隨着版本的更新或需求的增加去更換新版本。更痛苦的是你會發現一些 support 包的支持都要替換為 androidx 包的支持。

以上就是對 androidx 包的一個基本了解,更多詳細的內容請自己讀官方說明文檔。當然了,google 為了方便開發者升級到 androidx 包,在 Refactor(重構)按鈕下設置了一鍵替換 androidx 包的方法,比如這樣操作:

體驗一下:AndroidX

 

上面我只是做一個測試功能,我就不勾選備份了,在你的項目中,我建議你勾選備份,否則換版本時報錯是非常痛苦的一件事。好了,我們可以看到在依賴中都被替換為 androidx 開頭的庫文件了,本篇文章就帶你了解一下 androidx 以及在一些最新第三方庫(butterknife、glide等)引入為什么會失敗的原因,更多的驚喜就等待 google 官方提供給我們吧。

沒有關注小編都沒有動力更新文章了

各位看官給個關注唄

體驗一下:AndroidX


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM