Android React Native在Android Studio中执行bundleReleaseJsAndAssets 打包失败的解决方法

标签: AndroidReactNativegradletask
4971人阅读 评论(1) 收藏 举报
分类:

这个坑在文章记一次在Windows上搭建React Native Android环境踩过的坑中我已经提到过,当时找不到解决方法,只能开一个命令提示符终端独立执行打包。就像这样子

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

2
1

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:916725次
    • 积分:10178
    • 等级:
    • 排名:第1655名
    • 原创:164篇
    • 转载:5篇
    • 译文:0篇
    • 评论:700条
    博客专栏
    我的微博
    最新评论