React Native是啥砾省?
是一款用JavaScriptScript編寫原生(Android,iOS)應(yīng)用的框架鹰椒。
原理是啥沼死?
總體來(lái)看着逐,整套R(shí)eact Native框架分為三層,如下圖所示:
- Java層:該層主要提供了Android的UI渲染器UIManager(將JavaScript映射成Android Widget)以及一些其他的功能組件(例如:Fresco意蛀、Okhttp)等耸别。
- C++層:該層主要完成了Java與JavaScript的通信以及執(zhí)行JavaScript代碼兩件工作。JSCore县钥,即JavaScriptCore秀姐,JS解析的核心部分,IOS使用的是內(nèi)置的JavaScriptCore若贮,Androis上使用的是 https://webkit.org 家的jsc.so省有。
- JavaScript層:該層提供了各種供開發(fā)者使用的組件以及一些工具庫(kù)痒留。
通訊機(jī)制
關(guān)于整個(gè)RN的通信機(jī)制,可以用一句話來(lái)概括:
JNI作為C++與Java的橋梁锥咸,JSC作為C++與JavaScript的橋梁狭瞎,而C++最終連接了Java與JavaScript。
RN應(yīng)用通信橋結(jié)構(gòu)圖如下所示:
Java 調(diào)用 JS
JS 調(diào)用 Java
啟動(dòng)流程
JavaScript層組件渲染
從上圖我們可以很容易看出搏予,Java層的組件渲染分為以下幾步:
- JS層通過(guò)C++層把創(chuàng)建View的請(qǐng)求發(fā)送給Java層的UIManagerModule熊锭。
- UIManagerModule通過(guò)UIImplentation對(duì)操作請(qǐng)求進(jìn)行包裝。
- 包裝后的操作請(qǐng)求被發(fā)送到View處理隊(duì)列UIViewOperationQueue隊(duì)列中等待處理雪侥。
- 實(shí)際處理View時(shí)碗殷,根據(jù)class name查詢對(duì)應(yīng)的ViewNManager,然后調(diào)用原生View的方法對(duì)View進(jìn)行相應(yīng)的操作速缨。
用RN寫APP是怎樣的一種體驗(yàn)
Hello World快速體驗(yàn)
下載安裝Node锌妻,依次執(zhí)行(讀條)下面幾行代碼
npm install -g create-react-native-app
create-react-native-app AwesomeProject
cd AwesomeProject
npm start
順利執(zhí)行完后顯示如下結(jié)果,
根據(jù)提示可以通過(guò)掃碼在手機(jī)上看到代碼運(yùn)行效果
項(xiàng)目目錄結(jié)構(gòu)
React Native使用JSX寫項(xiàng)目的旬牲。
JSX is a syntax extension to JavaScript.
Introducing JSX
Basic
Hello World
布局
列表
網(wǎng)絡(luò)請(qǐng)求
自定義控件
RN Android混合開發(fā)
環(huán)境版本
react-native-cli: 2.0.1
react-native: 0.57.1
項(xiàng)目初始化
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 工程目錄結(jié)構(gòu)
JS 工程中的Android 工程結(jié)構(gòu)
MainApplication.java
MainActivity.java
ReactActivity.java
ReactActivityDelegate.java
ReactNativeHost.java
ReactNativeHost-structure
ReactNativeHost-createReactInstanceManager
ReactNativeHost-getMainModuleName
index.js
App.js
Android的 生命周期事件 是如何分發(fā)到 JS的世界 中的
ReactActivityDelegate
ReactInstanceManager
ReactContext
LifecycleEventListener
Android 調(diào) RN
1. Java 發(fā)送事件
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 調(diào) 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. 注冊(cè)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);