react native 这样理解运行机制

2023-05-16

移动开发中,native开发性能和效果上无疑是最好的。

但是在众多的情况下,native开发并不是最优的选择。当需求经常改动的时候,当预算有限的时候,当deadline很近的时候,native开发的成本也就体现出来了。

这时候,webview开始大放异彩,快速开发、无需重新发布版本、人员成本低的特点就显现出来了。(这里不指hybrid)。

当使用WebView后,就会逐渐发现,用户体验变得一塌糊涂,长时间的loading、操作dom造成的性能问题等等等等···

react native出现后,开辟的一条新的道路。

 

#0 分析一下下

公司现在的产品经历了2个大的版本更新后(纯native和部分WebView),现在要经历第三个重大版本的升级了。但这次版本出现了一些情况。

版面全部更新、人员有限、预算有限、开发时间短。这就是面临的问题所在。

hybrid是一整套的将html转为native的开发方式,但使用此方法将会面临的问题是:全部项目需要推翻重做、没有做过此类开发、没有经验。这对我们来说是一个很大的冒险。否决!

后续讨论后,使用native进行框架方面的搭建,大量使用webview进行过渡,开始逐步接入react native。

这样的好处就是基础内容仍然在可控范围内,可大量重复使用之前的代码。大量使用webview是为了保证项目可以在规定时间内赶工完成···纯属无奈之举。

使用react native是为了后续逐步替代webview而进行的。由于在rn方面没有很足的经验,只能一步一步的来,不敢一次性引入太多。

rn的好处就是在于可以在已有的项目中接入开发,而不像hybrid那样,需要全部替换才可以使用。这样就可以保证当rn遇到坑无法解决的时候,可以用较少的代价替换回native,保证项目的可控性。

 

#1 react native开发服务器

开发时,还是使用服务器来装载内容较为方便。这里使用的是ubuntu server 14.04。

这里还是提一句,rn是如何工作的。

在开发时,我们的框架是这样的:

当正式发布进入到生产环境时,开发服务器上所有的js文件将会被编译成包的形式,直接嵌入到客户端内。这时,已经不再需要开发服务器的支持了。(热更新后续继续写)

 

#2 详细的搭建步奏

#2.0  服务器搭建

由于资金有限,所以直接搞的虚拟机,安装的ubuntu server,基础设置:安装的node版本是v5.8.0。

这里就不详细的讲解node如何安装了···大家自行查找···网上很多···

首先安装Watchman和Flow

git clone https://github.com/facebook/watchman.git

cd watchman

git checkout v4.1.0 # the latest stable release

./autogen.sh

./configure

make

sudo make install

 

sudo npm install -g flow-bin

具体方法详见:https://facebook.github.io/react-native/docs/getting-started-linux.html#getting-started-on-linux (后面的安装android不需要)

然后创建一个存放代码的目录,比如我的目录是:/var/react/tykReact

切换到此目录下,执行下面语句进行初始化设置。

npm init

如果此语句在设置时不太会用,可在目录下创建package.json文件,文件中的内容如下:

{
  "name": "tykReact",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node_modules/react-native/packager/packager.sh"
  },
  "author": "LunaGao",
  "license": "MIT",
  "dependencies": {
    "react-native":"^0.20.0"
  }
}

注意:

1. dependencies下的"react-native":"^0.20.0"是必须的,直接npm install react-native安装在后续会出现问题。

2. scripts下的"start": "node_modules/react-native/packager/packager.sh"是为了启动使用的。(也可以不用)

 

此时,就可以执行以下语句进行下载react了。

npm install

这个时间比较长,需要耐心等待(我下载了1个小时...)。当然,最好加上sudo,以免出现没有权限等问题。

当安装好后,创建两个文件:index.ios.js和index.android.js。这是用来测试使用的。

index.ios.js


'use strict';

import React, {
  Text,
  View
} from 'react-native';

var styles = React.StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'red'
  }
});

class SimpleApp extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>This is a simple application.</Text>
      </View>
    )
  }
}

React.AppRegistry.registerComponent('TestView', () => SimpleApp);  

index.android.js


'use strict';

import React, {
  Text,
  View
} from 'react-native';

class MyAwesomeApp extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.hello}>Hello, World</Text>
      </View>
    )
  }
}
var styles = React.StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  hello: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
});

React.AppRegistry.registerComponent('TestView', () => MyAwesomeApp);  

两个文件的代码并不相同,这是直接从

https://facebook.github.io/react-native/docs/embedded-app-android.html#add-js-to-your-app

https://facebook.github.io/react-native/docs/embedded-app-ios.html#create-your-react-native-app 

复制而来。

至此,目录下应该是如下的样子:

请忽略116221-这样的文件和11f83243da86022a90031e1ca9d758bc,这些是服务启动后自动生成的。npm-debug.log.4046290474这个是错误的日志文件。

没问题后,我们开始启动服务,执行如下语句:

npm start

正常的情况如下图所示:

此时,打开浏览器,输入地址进行访问(192.168.0.203是我的服务器地址,需要替换成实际的地址,本机运行可直接使用localhost):

http://192.168.0.203:8081/index.ios.bundle?platform=ios

http://192.168.0.203:8081/index.android.bundle?platform=android

当返回类似于下图的内容时,证明服务器已经正常启动了(返回的内容其实很多···)。

#2.1 ios集成

创建一个测试用的ios项目,如:react-test

使用pod进行集成,首先要使用npm安装react-native(使用命令:npm install react-native),这个过程可能有点久,然后修改pod文件内容如下:

#platform :ios,'9.0'

use_frameworks!

 

target "react-test" do

  pod 'React', :path => './node_modules/react-native', :subspecs => [

  'Core',

  'RCTImage',

  'RCTNetwork',

  'RCTText',

  'RCTWebSocket',

  # Add any other subspecs you want to use in your project

  ]

end

pod如何使用这里就不做过多解释了。

然后,在storyboard中拖入一个view,把view的class改为ReactTestView。然后创建ReactTestView,继承自UIView。

ReactTestView.h


//
//  ReactTestView.h
//  react-test
//
//  Created by Luna Gao on 16/3/3.
//  Copyright © 2016年 gao.luna.com. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "RCTRootView.h"

@interface ReactTestView : UIView

@end  

ReactTestView.m


//
//  ReactTestView.m
//  react-test
//
//  Created by Luna Gao on 16/3/3.
//  Copyright © 2016年 gao.luna.com. All rights reserved.
//

#import "ReactTestView.h"

@implementation ReactTestView


- (void)awakeFromNib {
    NSString *urlString = @"http://192.168.0.203:8081/index.ios.bundle?platform=ios";
    NSURL *jsCodeLocation = [NSURL URLWithString:urlString];
//    NSURL *jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
    RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"TestView" initialProperties:nil launchOptions:nil];
    [self addSubview:rootView];
    rootView.frame = self.bounds;
}

@end  

然后就可以跑起来了。运行效果如下图(样子可能不一样,我的storyboard中增加了tab bar controller):

#2.2 Android集成

内容较多,请参考https://facebook.github.io/react-native/docs/embedded-app-android.html#prepare-your-app

注:这里时需要做 prepare-your-app 和 add-native-code 这两段中的内容。

将onCreate方法修改为:


super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mReactRootView = (ReactRootView) findViewById(R.id.test_js);
        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("index.android.bundle")
                .setJSMainModuleName("index.android")
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
        mReactRootView.startReactApplication(mReactInstanceManager, "TestView", null);  

在activity_main.xml文件中增加一个ReactRootView,id命名为:test_js。代码如下:


<com.facebook.react.ReactRootView
        android:id="@+id/test_js"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/test_text"/>  

请注意:在AndroidManifest.xml文件中增加


<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>  

此时运行代码,界面如下:

在命令行中执行:adb shell input keyevent 82

将弹出如下对话框:

点击Dev Settings,点击 Debug server host & port for device 选项如下图:

输入ip地址和端口号,如:192.168.0.203:8081,点击ok。

返回到应用打开页面,再次使用adb shell input keyevent 82命令,点击Reload JS,重新加载js文件。此时就会正常显示界面了。如下图:

 

#3 如何发布

发布时,我们需要先编译js文件。

在服务器中切换到刚刚的目录下(如/var/react/tykReact),执行如下两个命令:

sudo react-native bundle --minify --entry-file index.ios.js --bundle-output /tmp/ios.jsbundle --platform ios

sudo react-native bundle --minify --entry-file index.android.js --bundle-output /tmp/android.jsbundle --platform android

会在/tmp目录下出现两个文件:

ios.jsbundle 和 android.jsbundle。

将这两个文件分别放入到ios项目和android asset目录下,如下图:

  

修改ios代码:

ReactTestView.m


//    NSString *urlString = @"http://192.168.0.203:8081/index.ios.bundle?platform=ios";
//    NSURL *jsCodeLocation = [NSURL URLWithString:urlString];
    NSURL *jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"ios" withExtension:@"jsbundle"];
    RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"TestView" initialProperties:nil launchOptions:nil];
    [self addSubview:rootView];
    rootView.frame = self.bounds;  

注意:这里需要将ios.jsbundle文件加入到项目中。

修改android代码:


        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mReactRootView = (ReactRootView) findViewById(R.id.test_js);
        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("android.jsbundle")
                .setJSMainModuleName("android")
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
        mReactRootView.startReactApplication(mReactInstanceManager, "TestView", null);  

 

至此,项目就可以不在依赖开发服务器而直接使用安装包进行运行了~

另:debug模式需要在正式发布的时候取消掉。

一只孤独的猫咪神!喵!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

react native 这样理解运行机制 的相关文章

随机推荐

  • 基于Mysql、Servlet、JSP的简单作业管理系统

    文章目录 基于Mysql Servlet JSP的简单作业管理系统内容Servlet简单介绍JSP简单介绍mysql数据库设计代码实现运行结果 基于Mysql Servlet JSP的简单作业管理系统 代码地址 xff1a https gi
  • JavaEE_FinalProject

    基于Springboot xff0c jsp和mybatis的作业管理系统 系统需求 可登陆 xff0c 分为学生和老师两端 xff0c 根据账号进行不同分类 老师可以查看作业 xff0c 添加学生并且添加作业 学生可以查看作业 xff0c
  • Debian10搭建dhcp服务

    文章目录 1 安装dhcp服务2 设置网卡监听3 配置dhcp参数4 重启dhcp服务5 测试6 易错总结 1 安装dhcp服务 apt install y isc dhcp server 等待安装完成即可 xff08 这里有一个报错 xf
  • Debian10搭建ntp服务

    文章目录 1 所需设备2 任务描述3 安装ntp服务4 配置ntp服务器4 安装ntpdate客服端5 Debian10Client设置计划任务6 易错总结 1 所需设备 两台Debian10Debian10Server 网卡信息 xff1
  • win11安装的Ubuntu20.04子系统出现System has not been booted with systemd as init system (PID 1)问题的解决流程

    目录 一 前言 二 具体解决方法 第一步 xff1a 切换root用户至自己账号 第二步 xff1a 重新安装xrdp 第三步 xff1a 重新配置端口并启动xrdp 第四步 xff1a 打开远程连接窗口 第五步 xff1a 点击连接 xf
  • 方面级情感分析综述论文&论文+讲解+复现(ABSA)

    2022最新方面级别情感分析论文综述 A Survey on Aspect Based Sentiment Analysis Tasks Methods and Challenges 其中关于ASTE Data V2数据集的论文 1 论文地
  • 使用Go语言开发Qt界面

    Go 的 UI 库 Go 语言本身是没有 UI 库的 xff0c 不过有许多第三方的库支持将 Go 语言绑定到其他 UI 库 xff0c 比如 Qt GTK 参考地址 环境搭建 非 windows 或者需要参数说明的可以参考官方的wiki
  • GitHub AI 编程工具自动写代码神器Copilot插件体验

    简介 copilot 是一个基于 AI 的编程辅助工具 目前已经集成在了 vscode 中 xff0c 后续可能集成到更多平台和工具 xff0c 目前还是测试阶段 官网地址 https copilot github com 支持所有语言 c
  • WebStorm NodeJS

    按 Create New Project 選擇 Empty Project 選擇自己的Directory 作為Location Location 最尾是代表Project Name 改為Hello World 創建一個Javascript
  • wsl ubuntu22.04 conda环境安装labelImg解决xcb缺失问题

    labelImg 安装 pip install PyQt5 i https pypi tuna tsinghua edu cn simple pip install pyqt5 tools i https pypi tuna tsinghu
  • 7个大一C语言必学的程序 / C语言经典代码大全

    嗨 大家好 xff0c 这里是可莉 xff01 今天给大家带来的是7个C语言的经典基础代码 那一起往下看下去把 程序一 打印100到200之间的素数 include lt stdio h gt int main int i for i 61
  • 字符串转化为枚举类型

    需求 xff1a 通过配置文件中自定义传入枚举类型的值 span class token annotation punctuation 64 value span span class token punctuation span span
  • NAT和PAT的原理及配置

    文章目录 一 NAT1 NAT概述2 私有地址3 NAT工作原理4 NAT功能5 NAT包含4类地址6 NAT的实现方式 二 静态转换 xff08 Static Translation xff09 三 动态转换 xff08 Dynamic
  • Linux系统安装教程(手把手教学)

    文章目录 1 首先 xff0c 打开虚拟机 xff0c 点击新建虚拟机2 点击下一步 xff0c 再点击稍后安装3 操作系统选择Linux xff0c 版本选择CentOS7 64位4 命名虚拟机5 设置磁盘大小为100GB6 设置内存为4
  • NFS共享存储服务

    文章目录 引言一 NFS概述二 安装 nfs utils rpcbind 软件包三 NFS的特点四 实验步骤1 安装nfs和rpcbind软件2 设置共享目录3 启动 NFS服务并验证结果4 客户机中访问 NFS 共享资源4 1 手动挂载
  • 优化命令之Sar命令

    文章目录 引言一 sar简介1 sar命令常用格式2 常用选项3 常用参数 二 Sar常用性能数据三 CPU资源监控1 整体CPU使用统计 xff08 u xff09 2 各个CPU使用统计 P 3 将CPU使用情况保存到文件中 四 内存监
  • MySQL高级SQL语句

    文章目录 引言一 常用查询1 order by按关键字排序1 1 升序排序1 2 降序排序1 3 结合where进行条件过滤再排序1 4 多字段排序 2 and or判断2 1 and or 且与或的使用2 2 嵌套 多条件使用 3 dis
  • MongoDB搭建及基础操作

    文章目录 引言一 MongoDB概述1 什么是MongoDB2 MongoDB的特点3 MongoDB适用场景4 MongoDB概念解析 二 搭建MongoDB1 关闭系统防火墙和安全机制2 配置mongodb源仓库3 安装mongodb4
  • 【云原生之k8s】k8s之持久化存储PV、PVC

    文章目录 一 PV和PVC1 PV 概念2 PVC概念3 PV 与 PVC 之间的关系3 1 PV和PVC的生命周期3 2 一个PV从创建到销毁的具体流程3 3 三种回收策略3 4 查看pv pvc的定义方式 规格 4 两种PV的提供方式
  • react native 这样理解运行机制

    移动开发中 xff0c native开发性能和效果上无疑是最好的 但是在众多的情况下 xff0c native开发并不是最优的选择 当需求经常改动的时候 xff0c 当预算有限的时候 xff0c 当deadline很近的时候 xff0c n