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

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

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值