当前位置: 代码迷 >> Android >> 记一次在Windows上筹建React Native Android环境踩过的坑
  详细解决方案

记一次在Windows上筹建React Native Android环境踩过的坑

热度:95   发布时间:2016-04-27 22:07:59.0
记一次在Windows上搭建React Native Android环境踩过的坑

要说最近技术圈什么比较活跃,我想除了动态加载框架和热修复技术之外,非Facebook的React Native莫属了吧,其实RN对IOS的支持比较早,但是Android似乎难产了,直到9月份才刚开源。距离RN开源也有一段时间了,一直没有去学习,今天兴趣来潮,索性学一把吧。

本文假设你的Windows上安装了Android SDK,并配置好了环境变量。

安装Node.js

从官网https://nodejs.org/en/下载Node.js的windows版,也不知道为什么版本迭代这么快,之前安装的时候版本还是v0.12的,如今已经到了v5.1版,直接下载最新版就可以了。安装的时候记得勾选添加到环境变量中去,这样就不用手动添加环境变量了。

安装react-native-cli

打开命令行,输入npm install -g react-native-cli

初始化项目

命令行输入react-native init AwesomeProject,这一步如果卡死,建议翻个墙试试,本人在没翻墙前直接卡死在这一步,后来用了vpn翻了下墙就初始化好了。

这里写图片描述

启动React Native Server

命令行进入AwesomeProject目录,执行react-native start开启server

这里写图片描述

导入Android项目

使用Android Studio导入AwesomeProject/android项目,点击run运行(手机和电脑处于同一局域网内)。点击菜单,弹出调试相关的界面。

这里有一个深坑!
这里有一个深坑!
这里有一个深坑!

重要的事情说三次!

由于该调试界面使用的是悬浮窗弹出,而我使用的是小米实体机进行调试的,默认情况下会关闭所有应用的悬浮窗权限,这时候你怎么按菜单键或者玩死里摇手机,该界面都不会出来。解决方法就是在应用权限里开启悬浮窗权限。

之后按菜单键就可以弹出该界面了,修改server地址为你电脑上的ip地址加端口。

这样,运行程序是没问题了。

但是我们需要将其打包进apk,所以就需要用到打包命令。

打包Bundle

进入AwesomeProject目录,命令行执行

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

如果这里你报错了,类似下面的错误

C:\Users\Administrator\Desktop\AwesomeProject>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\releaseC:\Users\Administrator\Desktop\AwesomeProject\node_modules\promise\lib\done.js:10      throw err;      ^Error: Took too long to start server. Server logs:Wed, 18 Nov 2015 05:38:45 GMT ReactNativePackager:SocketServer server got ipc message { type: 'createSocketServer',  data:   { sockPath: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\react-packager-2bca409637da75daf8b8a17b9bdf33aa',     options:      { projectRoots: [Object],        assetRoots: [],        blacklistRE: [Object],        transformModulePath: 'C:\\Users\\Administrator\\Desktop\\AwesomeProject\\node_modules\\react-native\\packager\\transformer.js' } } }[13:38:45] <START> Building Dependency Graph[13:38:45] <START> Crawling File System[13:38:45] <START> Loading bundles layout[13:38:45] <END>   Loading bundles layout (1ms)Wed, 18 Nov 2015 05:38:45 GMT ReactNativePackager:SocketServer error creating server EACCESWed, 18 Nov 2015 05:38:45 GMT ReactNativePackager:SocketServer uncaught error Error: listen EACCES C:\Users\ADMINI~1\AppData\Local\Temp\react-packager-2bca409637da75daf8b8a17b9bdf33aa    at Object.exports._errnoException (util.js:856:11)    at exports._exceptionWithHostPort (util.js:879:20)    at Server._listen2 (net.js:1221:19)    at listen (net.js:1270:10)    at Server.listen (net.js:1360:5)    at new SocketServer (C:/Users/Administrator/Desktop/AwesomeProject/node_modules/react-native/packager/react-packager/src/SocketInterface/SocketServer.js:24:18)    at process.<anonymous> (C:/Users/Administrator/Desktop/AwesomeProject/node_modules/react-native/packager/react-packager/src/SocketInterface/SocketServer.js:177:7)    at emitTwo (events.js:87:13)    at process.emit (events.js:172:7)    at handleMessage (internal/child_process.js:686:10)Wed, 18 Nov 2015 05:41:12 GMT ReactNativePackager:SocketServer server got ipc message { type: 'createSocketServer',  data:   { sockPath: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\react-packager-2bca409637da75daf8b8a17b9bdf33aa',     options:      { projectRoots: [Object],        assetRoots: [],        blacklistRE: [Object],        transformModulePath: 'C:\\Users\\Administrator\\Desktop\\AwesomeProject\\node_modules\\react-native\\packager\\transformer.js' } } }[13:41:12] <START> Building Dependency Graph[13:41:12] <START> Crawling File System[13:41:12] <START> Loading bundles layout[13:41:12] <END>   Loading bundles layout (1ms)Wed, 18 Nov 2015 05:41:12 GMT ReactNativePackager:SocketServer error creating server EACCESWed, 18 Nov 2015 05:41:12 GMT ReactNativePackager:SocketServer uncaught error Error: listen EACCES C:\Users\ADMINI~1\AppData\Local\Temp\react-packager-2bca409637da75daf8b8a17b9bdf33aa    at Object.exports._errnoException (util.js:856:11)    at exports._exceptionWithHostPort (util.js:879:20)    at Server._listen2 (net.js:1221:19)    at listen (net.js:1270:10)    at Server.listen (net.js:1360:5)    at new SocketServer (C:/Users/Administrator/Desktop/AwesomeProject/node_modules/react-native/packager/react-packager/src/SocketInterface/SocketServer.js:24:18)    at process.<anonymous> (C:/Users/Administrator/Desktop/AwesomeProject/node_modules/react-native/packager/react-packager/src/SocketInterface/SocketServer.js:177:7)    at emitTwo (events.js:87:13)    at process.emit (events.js:172:7)    at handleMessage (internal/child_process.js:686:10)Wed, 18 Nov 2015 05:43:57 GMT ReactNativePackager:SocketServer server got ipc message { type: 'createSocketServer',  data:   { sockPath: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\react-packager-2bca409637da75daf8b8a17b9bdf33aa',     options:      { projectRoots: [Object],        assetRoots: [],        blacklistRE: [Object],        transformModulePath: 'C:\\Users\\Administrator\\Desktop\\AwesomeProject\\node_modules\\react-native\\packager\\transformer.js' } } }[13:43:57] <START> Building Dependency Graph[13:43:57] <START> Crawling File System[13:43:57] <START> Loading bundles layout[13:43:57] <END>   Loading bundles layout (1ms)Wed, 18 Nov 2015 05:43:57 GMT ReactNativePackager:SocketServer error creating server EACCESWed, 18 Nov 2015 05:43:57 GMT ReactNativePackager:SocketServer uncaught error Error: listen EACCES C:\Users\ADMINI~1\AppData\Local\Temp\react-packager-2bca409637da75daf8b8a17b9bdf33aa    at Object.exports._errnoException (util.js:856:11)    at exports._exceptionWithHostPort (util.js:879:20)    at Server._listen2 (net.js:1221:19)    at listen (net.js:1270:10)    at Server.listen (net.js:1360:5)    at new SocketServer (C:/Users/Administrator/Desktop/AwesomeProject/node_modules/react-native/packager/react-packager/src/SocketInterface/SocketServer.js:24:18)    at process.<anonymous> (C:/Users/Administrator/Desktop/AwesomeProject/node_modules/react-native/packager/react-packager/src/SocketInterface/SocketServer.js:177:7)    at emitTwo (events.js:87:13)    at process.emit (events.js:172:7)    at handleMessage (internal/child_process.js:686:10)Wed, 18 Nov 2015 05:55:30 GMT ReactNativePackager:SocketServer server got ipc message { type: 'createSocketServer',  data:   { sockPath: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\react-packager-2bca409637da75daf8b8a17b9bdf33aa',     options:      { projectRoots: [Object],        assetRoots: [],        blacklistRE: [Object],        transformModulePath: 'C:\\Users\\Administrator\\Desktop\\AwesomeProject\\node_modules\\react-native\\packager\\transformer.js' } } }[13:55:30] <START> Building Dependency Graph[13:55:31] <START> Crawling File System[13:55:31] <START> Loading bundles layout[13:55:31] <END>   Loading bundles layout (0ms)Wed, 18 Nov 2015 05:55:31 GMT ReactNativePackager:SocketServer error creating server EACCESWed, 18 Nov 2015 05:55:31 GMT ReactNativePackager:SocketServer uncaught error Error: listen EACCES C:\Users\ADMINI~1\AppData\Local\Temp\react-packager-2bca409637da75daf8b8a17b9bdf33aa    at Object.exports._errnoException (util.js:856:11)    at exports._exceptionWithHostPort (util.js:879:20)    at Server._listen2 (net.js:1221:19)    at listen (net.js:1270:10)    at Server.listen (net.js:1360:5)    at new SocketServer (C:/Users/Administrator/Desktop/AwesomeProject/node_modules/react-native/packager/react-packager/src/SocketInterface/SocketServer.js:24:18)    at process.<anonymous> (C:/Users/Administrator/Desktop/AwesomeProject/node_modules/react-native/packager/react-packager/src/SocketInterface/SocketServer.js:177:7)    at emitTwo (events.js:87:13)    at process.emit (events.js:172:7)    at handleMessage (internal/child_process.js:686:10)Wed, 18 Nov 2015 05:57:02 GMT ReactNativePackager:SocketServer server got ipc message { type: 'createSocketServer',  data:   { sockPath: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\react-packager-2bca409637da75daf8b8a17b9bdf33aa',     options:      { projectRoots: [Object],        assetRoots: [],        blacklistRE: [Object],        transformModulePath: 'C:\\Users\\Administrator\\Desktop\\AwesomeProject\\node_modules\\react-native\\packager\\transformer.js' } } }[13:57:02] <START> Building Dependency Graph[13:57:02] <START> Crawling File System[13:57:02] <START> Loading bundles layout[13:57:02] <END>   Loading bundles layout (0ms)Wed, 18 Nov 2015 05:57:02 GMT ReactNativePackager:SocketServer error creating server EACCESWed, 18 Nov 2015 05:57:02 GMT ReactNativePackager:SocketServer uncaught error Error: listen EACCES C:\Users\ADMINI~1\AppData\Local\Temp\react-packager-2bca409637da75daf8b8a17b9bdf33aa    at Object.exports._errnoException (util.js:856:11)    at exports._exceptionWithHostPort (util.js:879:20)    at Server._listen2 (net.js:1221:19)    at listen (net.js:1270:10)    at Server.listen (net.js:1360:5)    at new SocketServer (C:/Users/Administrator/Desktop/AwesomeProject/node_modules/react-native/packager/react-packager/src/SocketInterface/SocketServer.js:24:18)    at process.<anonymous> (C:/Users/Administrator/Desktop/AwesomeProject/node_modules/react-native/packager/react-packager/src/SocketInterface/SocketServer.js:177:7)    at emitTwo (events.js:87:13)    at process.emit (events.js:172:7)    at handleMessage (internal/child_process.js:686:10)    at [object Object]._onTimeout (C:/Users/Administrator/Desktop/AwesomeProject/node_modules/react-native/packager/react-packager/src/SocketInterface/index.js:82:7)    at Timer.listOnTimeout (timers.js:92:15)

这是个bug,详见https://github.com/facebook/react-native/issues/3997

解决方法就是修改AwesomeProject/node_modules/react-native/packager/react-packager/src/SocketInterface/index.js文件中40行附件的

  const sockPath = path.join(    tmpdir,    'react-packager-' + hash.digest('hex')  );

为下面的内容

  let sockPath = path.join(    tmpdir,    'react-packager-' + hash.digest('hex')  );  if (process.platform==='win32'){    sockPath = sockPath.replace(/^\//, '')    sockPath = sockPath.replace(/\//g, '-')    sockPath = '\\\\.\\pipe\\' + sockPath  }

之后将生成的index.android.bundle拷到assets目录即可。

这里也有一个深坑。

Android Studio中,android目录下的build.gradle会使用react.gradle,该文件中就是打包bundle的task

def config = project.hasProperty("react") ? project.react : [];def bundleAssetName = config.bundleAssetName ?: "index.android.bundle"def entryFile = config.entryFile ?: "index.android.js"// because elvis operatordef 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}

如果我们执行bundleReleaseJsAndAssets,或者bundleDebugJsAndAssets这两个task,不知道什么原因,总是报错,但是将对应的命令

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

复制到命令行执行,却是可以生成bundle文件的,然而上面的两个task最终执行的就是这条命令,但是无论怎么样它就是报错,最后无奈只能命令行生成,也无伤什么大雅。

如果知道这个问题原因是什么的,也请告知!

1楼qq_21430549前天 17:37
android弟好厉害
  相关解决方案