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

原创 2015年11月18日 23:04:01

要说最近技术圈什么比较活跃,我想除了动态加载框架和热修复技术之外,非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 and
roid --dev false --entry-file index.android.js --bundle-output C:\Users\Administ
rator\Desktop\AwesomeProject\android\app\build\intermediates\assets\release\inde
x.android.bundle --assets-dest C:\Users\Administrator\Desktop\AwesomeProject\and
roid\app\build\intermediates\res\merged\release
C:\Users\Administrator\Desktop\AwesomeProject\node_modules\promise\lib\done.js:1
0
      throw err;
      ^

Error: Took too long to start server. Server logs:
Wed, 18 Nov 2015 05:38:45 GMT ReactNativePackager:SocketServer server got ipc me
ssage { type: 'createSocketServer',
  data:
   { sockPath: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\react-packager-2bca40
9637da75daf8b8a17b9bdf33aa',
     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 se
rver EACCES
Wed, 18 Nov 2015 05:38:45 GMT ReactNativePackager:SocketServer uncaught error Er
ror: listen EACCES C:\Users\ADMINI~1\AppData\Local\Temp\react-packager-2bca40963
7da75daf8b8a17b9bdf33aa
    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_modu
les/react-native/packager/react-packager/src/SocketInterface/SocketServer.js:24:
18)
    at process.<anonymous> (C:/Users/Administrator/Desktop/AwesomeProject/node_m
odules/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 me
ssage { type: 'createSocketServer',
  data:
   { sockPath: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\react-packager-2bca40
9637da75daf8b8a17b9bdf33aa',
     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 se
rver EACCES
Wed, 18 Nov 2015 05:41:12 GMT ReactNativePackager:SocketServer uncaught error Er
ror: listen EACCES C:\Users\ADMINI~1\AppData\Local\Temp\react-packager-2bca40963
7da75daf8b8a17b9bdf33aa
    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_modu
les/react-native/packager/react-packager/src/SocketInterface/SocketServer.js:24:
18)
    at process.<anonymous> (C:/Users/Administrator/Desktop/AwesomeProject/node_m
odules/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 me
ssage { type: 'createSocketServer',
  data:
   { sockPath: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\react-packager-2bca40
9637da75daf8b8a17b9bdf33aa',
     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 se
rver EACCES
Wed, 18 Nov 2015 05:43:57 GMT ReactNativePackager:SocketServer uncaught error Er
ror: listen EACCES C:\Users\ADMINI~1\AppData\Local\Temp\react-packager-2bca40963
7da75daf8b8a17b9bdf33aa
    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_modu
les/react-native/packager/react-packager/src/SocketInterface/SocketServer.js:24:
18)
    at process.<anonymous> (C:/Users/Administrator/Desktop/AwesomeProject/node_m
odules/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 me
ssage { type: 'createSocketServer',
  data:
   { sockPath: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\react-packager-2bca40
9637da75daf8b8a17b9bdf33aa',
     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 se
rver EACCES
Wed, 18 Nov 2015 05:55:31 GMT ReactNativePackager:SocketServer uncaught error Er
ror: listen EACCES C:\Users\ADMINI~1\AppData\Local\Temp\react-packager-2bca40963
7da75daf8b8a17b9bdf33aa
    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_modu
les/react-native/packager/react-packager/src/SocketInterface/SocketServer.js:24:
18)
    at process.<anonymous> (C:/Users/Administrator/Desktop/AwesomeProject/node_m
odules/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 me
ssage { type: 'createSocketServer',
  data:
   { sockPath: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\react-packager-2bca40
9637da75daf8b8a17b9bdf33aa',
     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 se
rver EACCES
Wed, 18 Nov 2015 05:57:02 GMT ReactNativePackager:SocketServer uncaught error Er
ror: listen EACCES C:\Users\ADMINI~1\AppData\Local\Temp\react-packager-2bca40963
7da75daf8b8a17b9bdf33aa
    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_modu
les/react-native/packager/react-packager/src/SocketInterface/SocketServer.js:24:
18)
    at process.<anonymous> (C:/Users/Administrator/Desktop/AwesomeProject/node_m
odules/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 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
}

如果我们执行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最终执行的就是这条命令,但是无论怎么样它就是报错,最后无奈只能命令行生成,也无伤什么大雅。

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

React Native demo运行报错:Cannot find entry file index.android.js in any of the roots

android运行GaGaMall出现如图错误,怎么弄都不行,index.android.js明明在根目录的,头疼的要死...可是同事那边下的,在npm install后,拷贝过来又行了... ...

【原】Cannot find entry file index.ios.js [index.android.js] in any of the roots

今天在运行新的React Native项目时,出现了错误。 错误信息如图: 在stackoverflow上搜索了一下,发现很多人遇到过这个问题。React Native的github上也有相应的I...
  • s_521_h
  • s_521_h
  • 2017年08月08日 14:39
  • 994

初次接触到react-native,遇到的两个失误

初次接触到react-native,遇到的两个错误错误一D:\node\AwesomeProject>react-native run-android Starting JS server... Bu...

React Native Android错误总结

错误一提示:Exception in native call from JS java.lang.RuntimeException: ReferenceError: Can’t find varia...

集成 React Native 到现有的 Android 项目( Mac, Windows 通用版 )

集成 React Native 到现有的 Android 项目( Mac, Windows 通用版 ) 发表于 2016-10-26   |   分类于 Android学习   |     ...
  • oqqLHF
  • oqqLHF
  • 2017年10月10日 10:57
  • 72

F8App-ReactNative项目源码分析1-初体验

近期开始研究Facebook f8app项目,目标是理解Facebook官方React Native f8app的整体技术架构,给公司目前几个的React Native项目开发提供官方经验借鉴,并对原...
  • offbye
  • offbye
  • 2016年05月18日 22:26
  • 5542

Android项目中集成React Native

运行以下命令 : $ npm init 生成 package.json ,下面给出一份 Demo : { "name": "HelloWorld", "version": "0.0....

我在集成ReactNative过程中踩过的那些坑

1、react-native init 命令创建的项目不能以数字开头 例如react-native init 58RNProject非法,react-native init WubaRNProje...

React-Native编写针对平台的代码

前言我们在实际项目开发中,Android和IOS平台显示的效果可能并不相同,针对不同平台编写不同代码的需求, 下面举例说明React-Native工程下几种平台区分的方法,以供参考。用不同文件夹区分...

React Native入门——布局实践:开发京东客户端首页(一)

有了一些对React Native开发的简单了解,让我们从实战出发,一起来构建一个简单的京东客户端。 这篇文章会对京东客户端首页的布局进行简单的分析,并对搜索框部分的开发进行介绍,其他内容在后面的文章...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:记一次在Windows上搭建React Native Android环境踩过的坑
举报原因:
原因补充:

(最多只允许输入30个字)