React Native 开发初体验

935 阅读6分钟

前言

随着互联网的遇冷,前端如果只局限于 web 端开发的话,路会越走越窄,应该多朝夸端开发的方向拓展一下。最近研究了下使用 React Native 开发 App,这里分享下从搭建到构建一个 apk 的完整过程,以供参考学习。由于本人的 Mac 电脑还是 2018 年款的 8G 内存,跑不了 iOS 开发所需的环境,所以以下内容是在 windows 电脑以 Android 开发的角度书写的。

提醒:windows 电脑的内存最好是 32G 以上,否则在运行模拟器时,如果再运行其他一些耗内存的程序,会提示 内存不足 卡出来;还有就是注意一定要 科学上网,否则寸步难行;依赖安装的过程可能耗时比较长,需要耐心等待。

版本:"react": "18.3.1","react-native": "0.77.0"

代理说明

在应用首次编译打包时需要下载大量的依赖包,这一过程相当耗时;代理一般只会对浏览器上网有效,如果在终端使用的话可能会失效,你需要给自己的终端设置下代理,保证是通过代理去下载的。如图1是我的代理配置,在 android/gradle.properties 文件中配置相应的代理如下:

systemProp.http.proxyHost=127.0.0.1
systemProp.http.proxyPort=10810
systemProp.https.proxyHost=127.0.0.1
systemProp.https.proxyPort=10810

图1

环境搭建

安装依赖

作为前端开发,Node 环境应该都有,这里不多说,注意 Node 的版本应大于等于 18。

  • Java Development Kit [JDK] 17 - 不建议直接使用搜索引擎搜索下载,尝试过......有很多夹带私货的流氓软件;通过科学上网直接到 官网 下载,注意需要先注册登录才能下载,为了长远考虑发点时间注册下也是值得的;还有一点需要注意的是你的 React Native 版本,低于 0.73 版本的 React Native 需要 JDK 11 版本,而低于 0.67 的需要 JDK 8 版本;安装完成后执行 javac -version 输出版本号看是否安装成功,一般会自动设置环境变量的。

  • Yarn - 包管理工具建议使用 Yarn,这也是官方推荐的;执行 npm i -g --verbose yarn 就行了。
  • Android Studio - 直接从 官网 下载,安装界面中选择"Custom"选项,确保选中了以下几项 Android SDK, Android SDK Platform, Android Virtual Device ,如果选择框是灰的,可以先跳过,稍后再来安装这些组件,然后点击"Next"来安装选中的组件;Android Studio 默认会安装最新版本的 Android SDK,目前编译 React Native 应用需要的是Android 14 (UpsideDownCake)版本的 SDK,需要在 Android Studio 的 SDK Manager 中选择安装,SDK Manager 可以在欢迎界面的 More Actions 中找到,如果已经过了欢迎界面,也可以在菜单栏中找到,如图2,打开 SDK Manager 后,已安装的不用管,勾选如图3所示的 SDK,最后点击"Apply"来下载和安装这些组件;Android Studio 安装完成后需要设置环境变量,这里不赘述了,如图4所示。

图1

图2

图3

图4

创建项目

直接使用命令,安装最干净的模板:

npx @react-native-community/cli init AwesomeProject

注意:初始化的项目名称改成自己想要的,否则初始化好了再改有点小麻烦;使用 yarn 安装依赖,这里可以切换到 taobao 源安装,快多了。

模拟器和真机

开发的时候需要预览和调试,可以使用模拟器,也可以使用真机。

创建模拟器

Android Studio 安装好了后,默认是有一个模拟器的,这里根据 React Native 的需要创建一个 Tiramisu API Level 33 image 的模拟器。

真机连接

  1. 用数据线和电脑连接,电脑中出现手机设备才行,如下图;

  1. 打开usb调试,不细讲了,可以直接看 这里

编译运行

运行之前可以执行以下命令查看是否有连接的模拟器或真机设备,只保留一个设备就行了,因为太耗内存了,内存怪兽的略过......

adb devices

# 出现以下信息表示有2个设备连接
List of devices attached
emulator-5554           # Google emulator
14ed2fcc device         # Physical device

如果显示没有连接的设备也没关系,因为运行的时候会自动启动模拟器设备,直接在项目根目录执行:

yarn android

运行时自动启动的模拟器效果如下图:

生成 APK 包

Android 要求所有应用都有一个数字签名才会被允许安装在用户手机上,所以需要先生成一个签名密钥。这里我们直接使用keytool命令快速生成一个密钥。

  1. 找到 Java 安装的 bin 目录,如:C:\Program Files\Java\jdkx.x.x_x\bin,在该目录下创建一个终端,执行:
keytool -genkeypair -v -storetype PKCS12 -keystore reactapp-release-key.keystore -alias reactapp-key-alias -keyalg RSA -keysize 2048 -validity 10000

这条命令会要求你输入密钥库(keystore)和对应密钥的密码,这2个密码应该保持一致,最终会在当前目录创建一个叫reactapp-release-key.keystore的密钥库文件,有效期为 10000 天,将密钥库文件放到项目的 android/app 下(密钥库文件在提交时会自动忽略,不要将它提交到远程项目)。

  1. 找到 android/gradle.properties,添加如下代码
MYAPP_RELEASE_STORE_FILE=reactapp-release-key.keystore
MYAPP_RELEASE_KEY_ALIAS=reactapp-key-alias
MYAPP_RELEASE_STORE_PASSWORD=<这里输入自己设置的密码>
MYAPP_RELEASE_KEY_PASSWORD=<这里输入自己设置的密码>

3. 把签名配置加入到项目的 android/app/build.gradle 配置中。

...
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/app/build/outputs/apk/release 中。

cd android
./gradlew assembleRelease

开发实践

入口文件修改

创建项目的 entry file index.js 默认在项目根目录,将它改成熟悉的 SPA 框架目录,创建 src 目录,将 index.js,App.tsx,app.json 移入 src 目录,android/app/build.gradle 配置需要做相应的修改,如下:

    //  The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
    // entryFile = file("../js/MyApplication.android.js")
    entryFile = file("../../src/index.js")

底部导航器

需要安装 React Navigation 的 @react-navigation/native,@react-navigation/bottom-tabs 依赖包,在 src/App.tsx 中编写代码:

const navigationEmit = (options: any) => {
  return options;
};

// 创建底部标签
const Tabs = createBottomTabNavigator({
  initialRouteName: 'Home',
  screenOptions: {
    animation: 'fade',
  },
  tabBar: props => (
    <TabBar
      {...{
        ...props,
        navigation: {
          ...props.navigation,
          emit: options => navigationEmit(options),
        },
      }}
    />
  ),
  screens: {
    Home: {
      screen: Home,
      options: {
        tabBarLabel: '首页',
        headerShown: false,
        tabBarIcon: props => <HomeIcon {...props} />,
      },
    },
    Components: {
      screen: Components,
      options: {
        tabBarLabel: '组件',
        headerShown: false,
        tabBarIcon: props => <ComponentsIcon {...props} />,
      },
    },
    Api: {
      screen: Api,
      options: {
        tabBarLabel: '接口',
        headerShown: false,
        tabBarIcon: props => <ApiIcon {...props} />,
      },
    },
  },
});

// 创建根导航
const RootStack = createNativeStackNavigator({
  initialRouteName: 'Tabs',
  screenOptions: {
    animation: 'ios_from_right',
    headerStyle: {
      backgroundColor: screenBackgroundColor,
    },
  },
  screens: {
    Tabs: {
      screen: Tabs,
      options: {
        headerShown: false,
      },
    },
    'Components/ActivityIndicator': {
      screen: ActivityIndicator,
      options: {
        headerTitle: '加载提示',
      },
    },
    'Components/Button': {
      screen: Button,
      options: {
        headerTitle: '按钮',
      },
    },
    'Components/Modal': {
      screen: Modal,
      options: {
        headerTitle: '弹窗',
      },
    },
    'Api/Camera': {
      screen: Camera,
      options: {
        headerTitle: '相机',
      },
    },
  },
});

const Navigation = createStaticNavigation(RootStack);

export default function App(): React.JSX.Element {
  return (
    <>
      <StatusBar
        backgroundColor={screenBackgroundColor}
        barStyle="dark-content"
      />
      <SafeAreaProvider>
        <Navigation />
      </SafeAreaProvider>
    </>
  );
}

相机功能

使用第三方包 react-native-vision-camera,这里就省略了,具体可以看我的 github 项目地址。

附项目地址

github.com/vsdeeper/re…