1. 程式人生 > >Android React Native在Android Studio中執行bundleReleaseJsAndAssets 打包失敗的解決方法

Android React Native在Android Studio中執行bundleReleaseJsAndAssets 打包失敗的解決方法

react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output C:\Users\Administrator\Desktop\AwesomeProject\android\app\build\intermediates\assets\release\index.android.bundle --assets-dest C:\Users\Administrator\Desktop\AwesomeProject\android\app\build\intermediates
\res\merged\release

然而這不是最好的解決方法,我們最求的是自動化打包。這個bug更詳細的描述見can’t build release for android - Windows 7 。無意之下看到這個個issue,在該issue下的連結中找到了問題的解決方法,原文地址react-native-windows-apks,發現差不多該倉庫的主人也是最近遇到這個問題,因為看它的提交時間,基本上就是昨天提交的,而我遇到這個問題還要早它個幾天,但是當時由於技術水平,沒有找到解決方法,現在看到它這個暫時的解決方法真是開心啊。不多說,下面貼出解決方法。

由React Native生成的android專案,在app目錄下有一個react.gradle檔案,該檔案中的內容如下

def config = project.hasProperty("react") ? project.react : [];

def bundleAssetName = config.bundleAssetName ?: "index.android.bundle"
def entryFile = config.entryFile ?: "index.android.js"

// because elvis operator
def elvisFile(thing) {
    return thing ? file(thing) : null;
}

def reactRoot = elvisFile(config.root
) ?: file("../../") def jsBundleDirDebug = elvisFile(config.jsBundleDirDebug) ?: file("$buildDir/intermediates/assets/debug") def jsBundleDirRelease = elvisFile(config.jsBundleDirRelease) ?: file("$buildDir/intermediates/assets/release") def resourcesDirDebug = elvisFile(config.resourcesDirDebug) ?: file("$buildDir/intermediates/res/merged/debug") def resourcesDirRelease = elvisFile(config.resourcesDirRelease) ?: file("$buildDir/intermediates/res/merged/release") def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"] def jsBundleFileDebug = file("$jsBundleDirDebug/$bundleAssetName") def jsBundleFileRelease = file("$jsBundleDirRelease/$bundleAssetName") task bundleDebugJsAndAssets(type: Exec) { // create dirs if they are not there (e.g. the "clean" task just ran) doFirst { jsBundleDirDebug.mkdirs() resourcesDirDebug.mkdirs() } // set up inputs and outputs so gradle can cache the result inputs.files fileTree(dir: reactRoot, excludes: inputExcludes) outputs.dir jsBundleDirDebug outputs.dir resourcesDirDebug // set up the call to the react-native cli workingDir reactRoot commandLine "react-native", "bundle", "--platform", "android", "--dev", "true", "--entry-file", entryFile, "--bundle-output", jsBundleFileDebug, "--assets-dest", resourcesDirDebug enabled config.bundleInDebug ?: false } task bundleReleaseJsAndAssets(type: Exec) { // create dirs if they are not there (e.g. the "clean" task just ran) doFirst { jsBundleDirRelease.mkdirs() resourcesDirRelease.mkdirs() } // set up inputs and outputs so gradle can cache the result inputs.files fileTree(dir: reactRoot, excludes: inputExcludes) outputs.dir jsBundleDirRelease outputs.dir resourcesDirRelease // set up the call to the react-native cli workingDir reactRoot commandLine "react-native", "bundle", "--platform", "android", "--dev", "false", "--entry-file", entryFile, "--bundle-output", jsBundleFileRelease, "--assets-dest", resourcesDirRelease enabled config.bundleInRelease ?: true } gradle.projectsEvaluated { // hook bundleDebugJsAndAssets into the android build process bundleDebugJsAndAssets.dependsOn mergeDebugResources bundleDebugJsAndAssets.dependsOn mergeDebugAssets processDebugResources.dependsOn bundleDebugJsAndAssets // hook bundleReleaseJsAndAssets into the android build process bundleReleaseJsAndAssets.dependsOn mergeReleaseResources bundleReleaseJsAndAssets.dependsOn mergeReleaseAssets processReleaseResources.dependsOn bundleReleaseJsAndAssets }

而這個gradle當時寫的時候應該是針對mac來寫的,所以在windows上可能遇到了那麼一點問題,我們需要對該gradle檔案進行一點細微的修改,在該檔案最上面新增

import org.apache.tools.ant.taskdefs.condition.Os

將task bundleDebugJsAndAssetsbundleReleaseJsAndAssets中的執行語句註釋掉,也就是下面兩句語句進行註釋

commandLine "react-native", "bundle", "--platform", "android", "--dev", "true", "--entry-file",
            entryFile, "--bundle-output", jsBundleFileDebug, "--assets-dest", resourcesDirDebug
commandLine "react-native", "bundle", "--platform", "android", "--dev", "false", "--entry-file",
            entryFile, "--bundle-output", jsBundleFileRelease, "--assets-dest", resourcesDirRelease

對應的替換為

    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        commandLine "cmd", "/c", "react-native", "bundle", "--platform", "android", "--dev", "true", "--entry-file",
                entryFile, "--bundle-output", jsBundleFileDebug, "--assets-dest", resourcesDirDebug
    } else {
        commandLine "react-native", "bundle", "--platform", "android", "--dev", "true", "--entry-file",
                entryFile, "--bundle-output", jsBundleFileDebug, "--assets-dest", resourcesDirDebug
    }

  if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        commandLine "cmd","/c", "react-native", "bundle", "--platform", "android", "--dev", "false", "--entry-file",
                entryFile, "--bundle-output", jsBundleFileRelease, "--assets-dest", resourcesDirRelease
    } else {
        commandLine "react-native", "bundle", "--platform", "android", "--dev", "false", "--entry-file",
                entryFile, "--bundle-output", jsBundleFileRelease, "--assets-dest", resourcesDirRelease
    }

也就是對作業系統進行判斷,假設是windows,就在命令前面加上cmd /c,之後後面緊跟原命令,否則就像原來那樣執行。

相信這個bug在不就的將來會得到解決,這個只是臨時的解決方法,文章寫作時,React Native Android的版本為0.14.2