React Native發(fā)布APP之簽名打包APK

用React Native開(kāi)發(fā)好APP之后,如何將APP發(fā)布以供用戶使用呢?一款A(yù)PP的發(fā)布流程無(wú)外乎:簽名打包—>發(fā)布到各store這兩大步驟。本文將向大家分享如何簽名打包一款React Native APP。

眾所周知,Android要求所有的APP都需要進(jìn)行數(shù)字簽名后,才能夠被安裝到相應(yīng)的設(shè)備上。簽名打包一個(gè)Android APP已經(jīng)是每一位Android開(kāi)發(fā)者的家常便飯了。
那么如何簽名打包一款用React Native開(kāi)發(fā)的APP呢?
既然Android Studio中可以進(jìn)行APP的簽名打包,那我們可不可以用它進(jìn)行打包呢,實(shí)踐表明用Android Studio打包React Native APP不是一種推薦的方案。

為什么不用Android Studio打包React Native APP?

在發(fā)這篇博文前我曾試著用Android Studio打包React Native APP,編譯,打包,安裝各項(xiàng)指數(shù)正常,當(dāng)我欣喜在手機(jī)上打開(kāi)APP看一下效果時(shí),APP在啟動(dòng)時(shí)閃退了。多試幾次依然如此,這時(shí)讓我想起每次通過(guò)terminal安裝APP到模擬器上時(shí),launchPackager.command終端都會(huì)輸出http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false這樣一行信息,然后APP在啟動(dòng)頁(yè)加載一會(huì)才進(jìn)入應(yīng)用。通過(guò)瀏覽器訪問(wèn)上面的鏈接,發(fā)現(xiàn)鏈接返回的是一個(gè)js文件,打開(kāi)該文件發(fā)現(xiàn)文件中的代碼其實(shí)是我們寫(xiě)的 React Native 的 JS 代碼。
PS.

  1. 在開(kāi)發(fā)環(huán)境下,每次啟動(dòng)APP,都會(huì)連接JS Server將項(xiàng)目中編寫(xiě)的js文件代碼加載到APP(這也是React Native的動(dòng)態(tài)更新的精髓)。
  2. 簽名打包后的APK已經(jīng)從開(kāi)發(fā)環(huán)境變成了生產(chǎn)環(huán)境,自然不會(huì)在每次啟動(dòng)的時(shí)候連接JS Server加載相應(yīng)的js文件。所以導(dǎo)致APP因缺少相應(yīng)的js而無(wú)法啟動(dòng)。

既然Android Stuio打包行不通,那么我們采用React Native官方推薦的方式進(jìn)行簽名打包(下文會(huì)重點(diǎn)講解“通過(guò)官方推薦的方式簽名打包”),打包過(guò)程很順利,將打包好的APK安裝到手機(jī)上后,發(fā)現(xiàn)能正常運(yùn)行。
對(duì)比用Android Studio簽名打包生成的APK與用官方推薦方式簽名打包生成的APK,發(fā)現(xiàn)了它們?cè)诖笮∩虾蛢?nèi)容上都有所差別,如圖:
大小上的差別:

兩種打包方式apk大小差異.png

對(duì)比兩種打包方式發(fā)現(xiàn),它們所生成的apk在大小上相差幾百k。為什么會(huì)相差那么大呢,帶著這個(gè)疑問(wèn)我們就將兩個(gè)apk解壓之后看看他們內(nèi)部具體有什么不同。
apk內(nèi)部差別:

兩種方式簽名打包的APK內(nèi)部差別.png

上圖是解壓之后apk的內(nèi)部細(xì)節(jié),發(fā)現(xiàn)通過(guò)官方推薦的方式打包的apk多了兩個(gè)文件“index.android.bundle”與“index.android.bundle.meta”,打開(kāi)“index.android.bundle”發(fā)現(xiàn)其和從http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false獲取的文件內(nèi)容是一樣的,都是我們寫(xiě)的 React Native 的 JS 代碼。

結(jié)論

  1. 在開(kāi)發(fā)環(huán)境下,為方便調(diào)試,APP會(huì)在啟動(dòng)時(shí)從JS Server服務(wù)器將index.android.bundle文件加載到APP。
  2. 簽名打包后的APP變成了生產(chǎn)環(huán)境,此時(shí)APP會(huì)默認(rèn)從本地加載 index.android.bundle文件,由于通過(guò)Android Studio打包的APK沒(méi)有將index.android.bundle打包進(jìn)apk,所以會(huì)因缺少index.android.bundle而無(wú)法啟動(dòng)。

通過(guò)官方推薦的方式簽名打包APK

第一步:生成Android簽名證書(shū)

如果你已經(jīng)有簽名證書(shū)可以繞過(guò)此步驟。
簽名APK需要一個(gè)證書(shū)用于為APP簽名,生成簽名證書(shū)可以Android Studio以可視化的方式生成,也可以使用終端采用命令行的方式生成,需要的可以自行Google這里不再敖述。

第二步:設(shè)置gradle變量

  1. 將你的簽名證書(shū)copy到 android/app目錄下。
  2. 編輯~/.gradle/gradle.properties../android/gradle.properties(一個(gè)是全局gradle.properties,一個(gè)是項(xiàng)目中的gradle.properties,大家可以根據(jù)需要進(jìn)行修改) ,加入如下代碼:
MYAPP_RELEASE_STORE_FILE=your keystore filename  
MYAPP_RELEASE_KEY_ALIAS=your keystore alias  
MYAPP_RELEASE_STORE_PASSWORD=*****    
MYAPP_RELEASE_KEY_PASSWORD=*****  

提示:用正確的證書(shū)密碼、alias以及key密碼替換掉 *****。

第三步:在gradle配置文件中添加簽名配置

編輯 android/app/build.gradle文件添加如下代碼:

...  
android {  
    ...  
    defaultConfig { ... }  
    signingConfigs {  
        release {  
            storeFile file(MYAPP_RELEASE_STORE_FILE)  
            storePassword MYAPP_RELEASE_STORE_PASSWORD  
            keyAlias MYAPP_RELEASE_KEY_ALIAS  
            keyPassword MYAPP_RELEASE_KEY_PASSWORD  
        }  
    }  
    buildTypes {  
        release {  
            ...  
            signingConfig signingConfigs.release  
        }  
    }  
}  
...  

第四步:簽名打包APK

terminal進(jìn)入項(xiàng)目下的android目錄,運(yùn)行如下代碼:
./gradlew assembleRelease

簽名打包成功.png

簽名打包成功后你會(huì)在 "android/app/build/outputs/apk/"目錄下看到簽名成功后的app-release.apk文件。
提示:如果你需要對(duì)apk進(jìn)行混淆打包 編輯android/app/build.gradle:

/**     
 * Run Proguard to shrink the Java bytecode in release builds.  
 */  
def enableProguardInReleaseBuilds = true  

如何在gradle中不使用明文密碼?

上文中直接將證書(shū)密碼以明文的形式寫(xiě)在了gradle.properties文件中,雖然可以將此文件排除在版本控制之外,但也無(wú)法保證密碼的安全,下面將向大家分享一種方法避免在gradle中直接使用明文密碼。

通過(guò)“鑰匙串訪問(wèn)(Keychain Access)”工具保護(hù)密碼安全

下面闡述的方法只在OS X上可行。
我們可以通過(guò)將發(fā)布證書(shū)密碼委托在“鑰匙串訪問(wèn)(Keychain Access)”工具中,然后通過(guò)gradle訪問(wèn)“鑰匙串訪問(wèn)”工具來(lái)獲取證書(shū)密碼。

具體步驟:

  1. cmd+space打開(kāi)“鑰匙串訪問(wèn)(Keychain Access)”工具。
  2. 在登錄選項(xiàng)中新鑰匙串,如圖:
    通過(guò)“鑰匙串訪問(wèn)(Keychain Access)”工具保護(hù)密碼安全 .png

提示: 你可以在terminal中運(yùn)行如下命令檢查新建的鑰匙串是否成功。
security find-generic-password -s android_keystore -w

  1. 在build.gradle中訪問(wèn)你的秘鑰串,將下列代碼編輯到android/app/build.gradle中:
def getPassword(String currentUser, String keyChain) {
   def stdout = new ByteArrayOutputStream()
   def stderr = new ByteArrayOutputStream()
   exec {
       commandLine 'security', '-q', 'find-generic-password', '-a', currentUser, '-s', keyChain, '-w'
       standardOutput = stdout
       errorOutput = stderr
       ignoreExitValue true
   }
   //noinspection GroovyAssignabilityCheck
      stdout.toString().trim()
}
// Add this line
def pass = getPassword("YOUR_USER_NAME","android_keystore")
...
android {
    ...
    defaultConfig { ... }
    signingConfigs {
        release {
            storeFile file(MYAPP_RELEASE_STORE_FILE)
            storePassword pass // Change this
            keyAlias MYAPP_RELEASE_KEY_ALIAS
            keyPassword pass // Change this
        }
    }
    buildTypes {
        release {
            ...
            signingConfig signingConfigs.release
        }
    }
}
...

**注意事項(xiàng) **
鑰匙串訪問(wèn)(Keychain Access)工具只是幫我們托管了,證書(shū)密碼,證書(shū)明和alias還是需要我們?cè)?code>gradle.properties中設(shè)置一下的。

About

本文出自《React Native學(xué)習(xí)筆記》系列文章。
了解更多,可以關(guān)注我的GitHub
@https://crazycodeboy.github.io/

推薦閱讀

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容