美文网首页
React Native 初探

React Native 初探

作者: 詹徐照 | 来源:发表于2018-10-07 17:22 被阅读26次

React Native是啥?

是一款用JavaScriptScript编写原生(Android,iOS)应用的框架。

原理是啥?

总体来看,整套React Native框架分为三层,如下图所示:


image.png
  • Java层:该层主要提供了Android的UI渲染器UIManager(将JavaScript映射成Android Widget)以及一些其他的功能组件(例如:Fresco、Okhttp)等。
  • C++层:该层主要完成了Java与JavaScript的通信以及执行JavaScript代码两件工作。JSCore,即JavaScriptCore,JS解析的核心部分,IOS使用的是内置的JavaScriptCore,Androis上使用的是 https://webkit.org 家的jsc.so
  • JavaScript层:该层提供了各种供开发者使用的组件以及一些工具库。

通讯机制

关于整个RN的通信机制,可以用一句话来概括:

JNI作为C++与Java的桥梁,JSC作为C++与JavaScript的桥梁,而C++最终连接了Java与JavaScript。
RN应用通信桥结构图如下所示:

image
Java 调用 JS
image
JS 调用 Java
image

启动流程

image

JavaScript层组件渲染

image

从上图我们可以很容易看出,Java层的组件渲染分为以下几步:

  1. JS层通过C++层把创建View的请求发送给Java层的UIManagerModule。
  2. UIManagerModule通过UIImplentation对操作请求进行包装。
  3. 包装后的操作请求被发送到View处理队列UIViewOperationQueue队列中等待处理。
  4. 实际处理View时,根据class name查询对应的ViewNManager,然后调用原生View的方法对View进行相应的操作。

用RN写APP是怎样的一种体验

Hello World快速体验

下载安装Node,依次执行(读条)下面几行代码

npm install -g create-react-native-app
create-react-native-app AwesomeProject
cd AwesomeProject
npm start

顺利执行完后显示如下结果,


image

根据提示可以通过扫码在手机上看到代码运行效果
项目目录结构

image
React Native使用JSX写项目的。
JSX is a syntax extension to JavaScript.
Introducing JSX

Basic

Hello World


image

布局


image
列表
image

网络请求


网络请求

自定义控件

image

RN Android混合开发

环境版本
react-native-cli: 2.0.1
react-native: 0.57.1

项目初始化

choco install -y nodejs.install python2 jdk8
npm install -g react-native-cli
1. Install Android Studio
2. Install the Android SDK
3. Configure the ANDROID_HOME environment variable
Preparing the Android device
react-native init AwesomeProject
cd AwesomeProject
react-native run-android

从Android主入口到JS主入口

JS 工程目录结构


image

JS 工程中的Android 工程结构
MainApplication.java


image
MainActivity.java
image

ReactActivity.java


image
ReactActivityDelegate.java
image
ReactNativeHost.java
ReactNativeHost-structure
image
ReactNativeHost-createReactInstanceManager
image
ReactNativeHost-getMainModuleName
image

index.js


image
App.js
image

Android的 生命周期事件 是如何分发到 JS的世界 中的

ReactActivityDelegate


image

ReactInstanceManager


image
image
ReactContext
image

LifecycleEventListener


image

Android 调 RN

1. Java 发送事件

RCTDeviceEventEmitter.java

...
private void sendEvent(ReactContext reactContext,
                       String eventName,
                       @Nullable WritableMap params) {
  reactContext
      .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
      .emit(eventName, params);
}
...
WritableMap params = Arguments.createMap();
...
sendEvent(reactContext, "keyboardWillShow", params);

2. JavaScript 接受事件

import { DeviceEventEmitter } from 'react-native';
...

var ScrollResponderMixin = {
  mixins: [Subscribable.Mixin],


  componentWillMount: function() {
    ...
    this.addListenerOn(DeviceEventEmitter,
                       'keyboardWillShow',
                       this.scrollResponderKeyboardWillShow);
    ...
  },
  scrollResponderKeyboardWillShow:function(e: Event) {
    this.keyboardWillOpenTo = e;
    this.props.onKeyboardWillShow && this.props.onKeyboardWillShow(e);
  },

RN 调 Android

1. 声明JavaModule

  • extends ReactContextBaseJavaModule
  • getName()
  • @ReactMethod
public class ToastModule extends ReactContextBaseJavaModule {

  private static final String DURATION_SHORT_KEY = "SHORT";
  private static final String DURATION_LONG_KEY = "LONG";

  public ToastModule(ReactApplicationContext reactContext) {
    super(reactContext);
  }
  
  @Override
  public String getName() {
    return "ToastExample";
  }
  
  @ReactMethod
  public void show(String message, int duration) {
    Toast.makeText(getReactApplicationContext(), message, duration).show();
  }
}

2. 注册JavaModule

CustomToastPackage.java

public class CustomToastPackage implements ReactPackage {

  @Override
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    return Collections.emptyList();
  }

  @Override
  public List<NativeModule> createNativeModules(
                              ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>();

    modules.add(new ToastModule(reactContext));

    return modules;
  }

}

MainApplication.java

// MainApplication.java

...
import com.your-app-name.CustomToastPackage; // <-- Add this line with your package name.
...

protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
            new MainReactPackage(),
            new CustomToastPackage()); // <-- Add this line with your package name.
}

3. 在JavaScript中使用JavaModule

Wrap the native module in a JavaScript module

/**
 * This exposes the native ToastExample module as a JS module. This has a
 * function 'show' which takes the following parameters:
 *
 * 1. String message: A string with the text to toast
 * 2. int duration: The duration of the toast. May be ToastExample.SHORT or
 *    ToastExample.LONG
 */
import {NativeModules} from 'react-native';
module.exports = NativeModules.ToastExample;

Use the module

import ToastExample from './ToastExample';

ToastExample.show('Awesome', ToastExample.SHORT);

参考资料

相关文章

  • React Native初探(三)- Mac

    在React Native初探(一) - Mac和React Native初探(二)- Mac中,很简陋但是能用的...

  • React Native 相关

    React Native 初探 https://www.cnblogs.com/yexiaochai/p/6042...

  • 2018-05-23

    Lottie Android 初探 Lottie是一个支持Android、iOS、React Native,并由 ...

  • Lottie Android 初探

    Lottie Android 初探 Lottie是一个支持Android、iOS、React Native,并由 ...

  • 菜鸟初探React Native 回合一

    React Native初探 前言 很久之前就想学习一下React Native了,但是一直没有落地的机会,我一直...

  • Paper Collection-Dynamic Deploym

    bang'blog React Native 初探(iOS) JSPatch官方解读 通过动态库的方式实现动态部署++

  • React Native 初探

    React Native是啥? 是一款用JavaScriptScript编写原生(Android,iOS)应用的框...

  • React Native 初探

    React Native是啥? 是一款用JavaScriptScript编写原生(Android,iOS)应用的框...

  • React Native 初探

    安装Chocolatey @powershell -NoProfile -ExecutionPolicy Bypa...

  • 初探React native

    首先送上中文链接 reactnative 安装环境的时候遇到不少坑,差点放弃。 使用命令行 brew instal...

网友评论

      本文标题:React Native 初探

      本文链接:https://www.haomeiwen.com/subject/cenlaftx.html