写在前面:
随着android studio和react native的更新,当前react native中文网的安装教程已经有一些不能正常使用,经过几天的摸索,成功运行了react native在模拟器和真机
可能会使用到的相关免费工具,greenhub,watt toolkit
一、安装步骤
跟随react native中文网的安装教程,一步步推进。我当前的安装环境是windows + 安卓
1. 安装node.js
推荐使用nvm-windows,[下载地址](https://github.com/coreybutler/nvm-windows/releases),进行node版本管理,使用比nvm-desktop简单,可以在任意位置win + r 打开cmd命令行窗口进行node版本切换
常用的nvm命令
nvm list 查看当前安装的node版本列表
nvm list available 查看可用的nvm 列表
nvm install [版本号] 安装对应的nvm版本
nvm use [版本号] 安装成功后运行改命令可以切换到对应的node版本
nvm uninstall [版本号] 卸载指定的node版本
常用的node命令
node -v 查看正在运行的node版本号,可以以此验证node是否安装成功
npm -v 查看当前的npm版本号
npm i pnpm -g 全局安装pnpm包管理工具,使用的是国内代理,在国内使用,安装速度更快,同时支持monorepo,是vue源代码指定的包管理工具
npm i yarn -g 全局安装yarn包管理工具,是RN官方推荐的包管理工具
设置npm的淘宝镜像代理
npm config set registry [https://registry.npmmirror.com](https://registry.npmmirror.com/)
2. 安装JDk 17, 最新版本的RN要求JDK 17, 下载地址
最新版本的java不需要自己配置环境变量,找一个安装位置,无脑下一步
java --version 查看Java是否安装成功以及对应的版本
javac --version 查看对应的java编译工具的版本
3. 安装Android Studio,下载地址,设置环境变量
下载完成之后,建议不要修改默认的安装位置,一直点击下一步,按照提示,选择好Android Sdk的保存位置,正常安装,一次成功更好,我是踩坑了很多次,Android Studio无法完全卸载干净,浪费了很多时间,下面总结关键操作步骤
设置环境变量
打开win 11设置页面,找到【高级系统设置】
找到系统变量里面的Path,将其余的设置添加进去
%ANDROID_HOME%\platform-tools
%ANDROID_HOME%\emulator
%ANDROID_HOME%\tools
%ANDROID_HOME%\tools\bin
设置正确的Android studio
以下是我能正常运行的所有的插件
最后点击apply,Android Studio会自动下载勾选的插件
创建一个安卓虚拟机
4. 创建新项目
使用npx react-native@latest init AwesomeProject 命令克隆一个RN项目到本地,AwesomeProject是默认的项目名。
设置完成后,可以使用
npx react-native doctor
命令检查当前环境是否安装成功,
这条命令报错是因为虚拟机没有被拉起,如果虚拟机的环境变量设置正确了,可以使用
emulator -avd [虚拟机名字,之前推荐不要有空格的那个]
来先拉起虚拟机,然后再运行npm run android命令运行项目,没有设置好环境变量,虚拟机拉起失败的话,可以再次对照检查一下上述步骤。(直接进入Android SDK的安装位置,找到emulator文件夹,文件管理器地址栏输入cmd,回车,输入emulator -avd [虚拟机名字,之前推荐不要有空格的那个]命令尝试直接拉起)。找不到AppData文件夹的话,对照下图打开显示隐藏的文件选项
5. 使用真机调试
使用usb连接电脑,找到手机设置-> 连续点击版本号进入开发者模式 -> 进入开发者模式菜单 -> 打开usb调试 -> 手机任务栏下拉选择文件管理选项 -> 在弹出框中选择允许usb调试 -> 运行npm run android 命令,根据提示将应用安装到手机上,就可以实现真机的热更新开发
6. 最后附上到现在为止项目中涉及到的三方库,包括了lottie动画库,图标库,路由跳转,常用加密插件,以及动画库
{
"name": "AwesomeProject",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"emulator": "emulator -avd Pixel_8_Pro",
"ios": "react-native run-ios",
"lint": "eslint .",
"start": "react-native start",
"test": "jest"
},
"dependencies": {
"@react-native-async-storage/async-storage": "^1.23.1",
"@react-navigation/bottom-tabs": "^6.5.20",
"@react-navigation/drawer": "^6.6.15",
"@react-navigation/native": "^6.1.17",
"@react-navigation/native-stack": "^6.9.26",
"babel-plugin-module-resolver": "^5.0.0",
"lottie-ios": "^3.2.3",
"lottie-react-native": "^6.7.0",
"react": "18.2.0",
"react-native": "0.73.6",
"react-native-animatable": "^1.4.0",
"react-native-base64": "^0.2.1",
"react-native-beautiful-table": "^1.0.3",
"react-native-gesture-handler": "^2.15.0",
"react-native-md5": "^1.0.0",
"react-native-reanimated": "^3.8.1",
"react-native-safe-area-context": "^4.9.0",
"react-native-screens": "^3.29.0",
"react-native-vector-icons": "^10.0.3"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@react-native/babel-preset": "0.73.21",
"@react-native/eslint-config": "0.73.2",
"@react-native/metro-config": "0.73.5",
"@react-native/typescript-config": "0.73.1",
"@types/react": "^18.2.6",
"@types/react-native-vector-icons": "^6.4.18",
"@types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.6.3",
"eslint": "^8.19.0",
"jest": "^29.6.3",
"prettier": "2.8.8",
"react-test-renderer": "18.2.0",
"typescript": "5.0.4"
},
"resolutions": {
"lottie-react-native": "^6.7.0"
},
"engines": {
"node": ">=18"
}
}
二、生成安卓安装包
1.进入应用的android/app目录,打开cmd窗口,生成签名密钥
Android 要求所有应用都有一个数字签名才会被允许安装在用户手机上,而国内几大手机厂商自定义的系统应用安装前都有一个签名校验的过程,未在手机厂商的应用市场注册的应用安装的时候会有风险提示,自己写的应用,根据提示进行操作即可
keytool -genkeypair -v -storetype PKCS12 -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysiz
运行命令后会要求输入一系列的参数,除了密钥是需要记住的,其余参数均为可选参数
2. 返回android根目录,找到gradle.properties文件,在其最后配置安卓环境变量
MYAPP_RELEASE_STORE_FILE=my-release-key.keystore
MYAPP_RELEASE_KEY_ALIAS=my-key-alias
MYAPP_RELEASE_STORE_PASSWORD=刚才设置的密钥
MYAPP_RELEASE_KEY_PASSWORD=刚才设置的密钥
3.把签名配置加入到项目的 gradle 配置中
需要注释掉原来debug相关的配置
...
android {
...
defaultConfig { ... }
signingConfigs {
release {
if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
storeFile file(MYAPP_RELEASE_STORE_FILE)
storePassword MYAPP_RELEASE_STORE_PASSWORD
keyAlias MYAPP_RELEASE_KEY_ALIAS
keyPassword MYAPP_RELEASE_KEY_PASSWORD
}
}
}
buildTypes {
release {
...
signingConfig signingConfigs.release
}
}
}
...
4.生成apk安装包
返回android目录,运行
./gradlew assembleRelease
命令,即可生成生成安装包,生成的 APK 文件位于android/app/build/outputs/apk/release/app-release.apk
三、推荐的第三方库
写在前面,
- react native的依赖管理很神奇,经常会出现新装的依赖会与其它依赖冲突的问题,这时候就需要删掉node_modules,重新安装依赖
- 虽然是实时热更新,但是新安装的依赖很多时候会出现无法解析的问题,这时候就需要
yarn run android重启项目
1、组件库 react native elements
类似于前端ant design的一个组件库,但是功能没有antd强大,可以凑合用
2、路由库 react-navigation
路由库,可以实现路由导航,内置底部导航栏导航组件
3、动画库react-native-animatable
可以实现一些动画,但是会有肉眼可见的卡顿,跟原生比不了
4、图标库react-native-vector-icons
内置了很多图标,颜色支持自定义
5、动态图标库lottie-react-native
基于lottie实现的动画,用json的格式保存,类似于svg,放大缩小无损
6、持久化存储库@react-native-async-storage/async-storage
类似于网页端localstorage的功能,大小限制一般是在6M
7、md5加密 react-native-md5
8、base64 加密react-native-base64
9、图片预览插件react-native-image-zoom-viewer
对组件进行二次封装,暂时只需要传入一个url,可以实现对应图片的放大预览,缩放,长按保存,点击关闭,下滑关闭。
import React, { useState } from 'react'
import { Image, Modal, TouchableOpacity } from 'react-native'
import ImageViewer from 'react-native-image-zoom-viewer'
type MineAvatorProps = {
url: string
}
const MineAvator = ({ url }: MineAvatorProps) => {
const [showImage, setShowImage] = useState(false)
const handleCancel = () => {
setShowImage(false)
}
return (
<>
<Modal visible={showImage} transparent={true}>
<ImageViewer
imageUrls={[{ url }]}
onCancel={handleCancel}
onClick={handleCancel}
enableSwipeDown
/>
</Modal>
<TouchableOpacity onPress={() => setShowImage(true)}>
<Image source={{ uri: url }} style={{ width: 80, height: 80, borderRadius: 10 }} />
</TouchableOpacity>
</>
)
}
export default MineAvator
四、踩坑解决思路
1、使用react-navigation的bottom-tabs的时候,进入子页面底部导航栏没有自动隐藏
全局设置一个context,作用通过tabBarStyle控制底部状态栏的显示和隐藏
// 部分代码,代码不全,体现一个思路
// 底部导航栏的路由组件
export const ShowTabBar = createContext(null)
function App() {
const [showTabBar, setShowTabBar] = useState(true)
return (
<ShowTabBar.Provider value={{ showTabBar, setShowTabBar }}>
<Tab.Screen
name="ScreenNotice"
key={123}
component={ScreenNotice}
options={{
title: '消息通知',
headerShown: false,
tabBarIcon: ({ color }) => (
<IconM name="bell-ring" size={navBarSettings.tabBarIconSize} color={color} />
),
tabBarStyle: showTabBar ? {} : { display: 'none' },
}}
/>
</ShowTabBar.Provider>
)
}
// 业务组件
function Use({ navigation }) {
const { setShowTabBar } = useContext(ShowTabBar)
useEffect(() => {
// 监听当前页面的focus事件,控制底部tab是否显示
navigation.addListener('focus', e => {
// true/false, 显示/隐藏
setShowTabBar(true)
})
}, [])
return ()
}