标签:android react node-js rn facebook
要说最近技术圈什么比较活跃,我想除了动态加载框架和热修复技术之外,非Facebook的React Native莫属了吧,其实RN对IOS的支持比较早,但是Android似乎难产了,直到9月份才刚开源。距离RN开源也有一段时间了,一直没有去学习,今天兴趣来潮,索性学一把吧。
本文假设你的Windows上安装了Android SDK,并配置好了环境变量。
从官网https://nodejs.org/en/下载Node.js的windows版,也不知道为什么版本迭代这么快,之前安装的时候版本还是v0.12的,如今已经到了v5.1版,直接下载最新版就可以了。安装的时候记得勾选添加到环境变量中去,这样就不用手动添加环境变量了。
打开命令行,输入npm install -g react-native-cli
命令行输入react-native init AwesomeProject,这一步如果卡死,建议翻个墙试试,本人在没翻墙前直接卡死在这一步,后来用了vpn翻了下墙就初始化好了。
命令行进入AwesomeProject目录,执行react-native start开启server
使用Android Studio导入AwesomeProject/android项目,点击run运行(手机和电脑处于同一局域网内)。点击菜单,弹出调试相关的界面。
这里有一个深坑!
这里有一个深坑!
这里有一个深坑!
重要的事情说三次!
由于该调试界面使用的是悬浮窗弹出,而我使用的是小米实体机进行调试的,默认情况下会关闭所有应用的悬浮窗权限,这时候你怎么按菜单键或者玩死里摇手机,该界面都不会出来。解决方法就是在应用权限里开启悬浮窗权限。
之后按菜单键就可以弹出该界面了,修改server地址为你电脑上的ip地址加端口。
这样,运行程序是没问题了。
但是我们需要将其打包进apk,所以就需要用到打包命令。
进入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最终执行的就是这条命令,但是无论怎么样它就是报错,最后无奈只能命令行生成,也无伤什么大雅。
如果知道这个问题原因是什么的,也请告知!
版权声明:本文为博主原创文章,未经博主允许不得转载。
记一次在Windows上搭建React Native Android环境踩过的坑
标签:android react node-js rn facebook
原文地址:http://blog.csdn.net/sbsujjbcy/article/details/49914601