一. 序
當我們在 Android Studio 中,直接 Run 一個項目時,AS 會自動打一個 Debug 的 Apk,並通過 ADB 命令,將 App 安裝到我們連接的設備上。
這個 Run 出來的 Apk,在工程的 build/
目錄可以找到。如果你還想把這個 Apk 分享出去,搶先體驗功能,不好意思,正常情況下,這個 Apk 是無法安裝的。
接下來看看,是什麼導致 Run 出來的 APK 無法安裝。
二. Run 的 Apk
2.1 testOnly 屬性
我們知道,AS Run 起來的 Apk,會使用 Debug 簽名進行簽名,不過安裝不上,並不是簽名的問題。
而是因爲,Run 出來的 APK,會在 AndroidManifest.xml
文件中,增加 android:testOnly
屬性,正是因爲這個屬性,阻止了我們使用正常方式安裝 APK。
android:testOnly
對應的是 ApplicationInfo 中的 FLAG_TEST_ONLY
,這個 Flag 最早在 Api Level 4 就已經存在,使用它不會有任何低版本兼容的問題。
當你使用 adb install
安裝 android:testOnly="true"
的包時,輸出的錯誤信息,明確的標記了無法安裝一個 TEST_ONLY
的包。
Failed to install app-debug.apk: Failure [INSTALL_FAILED_TEST_ONLY: installPackageLI]
對於多年 Android 經驗的開發者來說,如果曾經將 Run 出來的 Debug.apk 分享給別人時,早年間是可以正常安裝的,那 testOnly
屬性是在什麼時候被加在 Debug.apk 上的呢?
雖然 FLAG_TEST_ONLY 屬性最早可以追溯到 APK Level 4,但是它其實是在 Android Studio 3.0 上才被默認加入到 APK 中的。只有 AS 3.0+ 的 IDE 上,Run 出來的 APK,纔會默認帶上 testOnly
屬性,這將阻止你使用正常的方式安裝。
簡單小結一下:
我們無法通過正常安裝方式,安裝一個帶有
android:testOnly="true"
的 Apk。這個屬性,是在 AS 3.0 中加入的。
這就是爲什麼你無法安裝 Run 出來的 Debug.apk。
2.2 爲什麼要這麼設計?
這個問題,對於大多數開發者來說,基本上不是問題。
因爲我們只要保證正常的提測、發佈流程,基本上是很難將一個 Run 出來的 Apk 分享給別人的。
testOnly
只是一個標記,標記了它是一個測試的版本,其實並沒有任何實質性的東西。如果因爲流程上的失誤,將其分享出去,這也是很容易就可以發現的,因爲這個包正常流程無法安裝。
2.3 是不是真的無法安裝?
如果我們非要安裝一個帶有 testOnly 的 Apk,其實也是有辦法的,否則 AS 又是如何將 Run 起來的包,安裝到設備上的呢?
解決方法也很簡單,只需要在 adb install
上,增加 -t
即可。
adb install -t debug.apk
如果想要阻止 AS 在 Run 時,構建的 APK 中增加 android:testOnly
標記,也是有辦法的。
可以在 gradle.properties 文件中,增加 android.injected.testOnly=false
即可。
# gradle.properties
android.injected.testOnly=false
然後這個 android:testOnly
屬性就會消失。
三. 小結時刻
AS Run 出來的 Apk,之所以無法安裝,是因爲其攜帶了 FLAG_TEST_ONLY
這個 Flag,它會阻止我們使用正常的方式安裝。想要安裝,可以通過 adb install -t
來解決。
雖然這個 Flag 初始於 API Level 4,但是它在 AS 3.0 中,才被默認加入。想要去掉可以通過增加 android.injected.testOnly=false
來實現。
這個問題當個小知識點了解一下即可,正常我們也不會遇到這樣的問題,畢竟誰會把一個 Run 出來的包出去呢。
references:
https://commonsware.com/blog/2017/10/31/android-studio-3p0-flag-test-only.html
本文對你有幫助嗎?留言、轉發、點好看是最大的支持,謝謝!
「聯機圓桌」????推薦我的知識星球,一年 50 個優質問題,上桌聯機學習。
公衆號後臺回覆成長『成長』,將會得到我準備的學習資料,也能回覆『加羣』,一起學習進步。