ReactNative插件開發(fā)
安裝
$ npm install -g yarn react-native-cli
$ npm install -g react-native-create-library
創(chuàng)建HelloWorld
$ react-native init AwesomeProject
編譯并運(yùn)行 React Native 應(yīng)用
$ cd AwesomeProject
$ react-native run-android
步驟
1. 創(chuàng)建插件項(xiàng)目
選擇一個(gè)額外的目錄拂檩,開始創(chuàng)建插件疙咸。
react-native-create-library --package-identifier com.reactlibrary --platforms android,ios MyLibrary
2. 編寫插件Module
進(jìn)入創(chuàng)建好的插件目錄铜涉,找到xxxModule.java的文件臼隔,該Module它可以實(shí)現(xiàn)一些JavaScript所需的功能沉填。
package com.reactlibrary;
import android.widget.Toast;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
public class RNMyLibraryModule extends ReactContextBaseJavaModule {
private final ReactApplicationContext reactContext;
private static final String DURATION_SHORT_KEY = "SHORT";
private static final String DURATION_LONG_KEY = "LONG";
public RNMyLibraryModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}
@Override
public String getName() {
return "RNMyLibrary";
}
@Nullable
@Override
public Map<String, Object> getConstants() {
Map<String, Object> constants = new HashMap<>();
constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
return constants;
}
@ReactMethod
public void show(String message, int duration) {
Toast.makeText(getReactApplicationContext(), message, duration).show();
}
}
getName()這個(gè)函數(shù)用于返回一個(gè)字符串名字,這個(gè)名字在 JavaScript 端標(biāo)記這個(gè)模塊霞扬。
getConstants()返回了需要導(dǎo)出給 JavaScript 使用的常量糕韧,它并不一定需要實(shí)現(xiàn)。
注解@ReactMethod喻圃,用于提供給JavaScript調(diào)用的方法萤彩,方法的返回類型必須為void。React Native 的跨語(yǔ)言訪問(wèn)是異步進(jìn)行的斧拍,所以想要給 JavaScript 返回一個(gè)值的唯一辦法是使用回調(diào)函數(shù)或者發(fā)送事件雀扶。
3. 編寫插件Package
注冊(cè)這個(gè)模塊。我們需要在應(yīng)用的 Package 類的createNativeModules方法中添加這個(gè)模塊肆汹。
package com.reactlibrary;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.bridge.JavaScriptModule;
public class RNMyLibraryPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(new RNMyLibraryModule(reactContext));
}
// Deprecated from RN 0.47
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
4. 編寫index.js愚墓,用于返回native模塊
import { NativeModules } from 'react-native';
const { RNMyLibrary } = NativeModules;
export default RNMyLibrary;
其中,RNMyLibrary這個(gè)名字需要與Module中g(shù)etName()返回的字符串相同县踢。
5. 引入插件
方法一:
打開插件目錄下package.json转绷,記錄name的值伟件。在這里示例為"name": "react-native-my-library"硼啤。接下來(lái)會(huì)link它。
使用命令行終端cd到插件根目錄斧账,執(zhí)行
$ yarn link
cd到項(xiàng)目根目錄谴返,執(zhí)行
$ yarn link "react-native-my-library"
使鏈接生效。它可以讓react native工程中的android和ios原生項(xiàng)目咧织,自動(dòng)去生成依賴(會(huì)在原生項(xiàng)目中生成配置代碼)嗓袱。在項(xiàng)目根目錄執(zhí)行
$ react-native link "react-native-my-library"
方法二:
打開項(xiàng)目目錄中的package.json,修改dependencies
"dependencies": {
"react": "16.6.0-alpha.8af6728",
"react-native": "0.57.4",
"react-native-my-library": "file:../MyLibrary"
}
react-native-my-library為插件的name习绢,file后面帶的是插件目錄相對(duì)當(dāng)前項(xiàng)目的路徑渠抹。然后cd到項(xiàng)目根目錄,執(zhí)行
$ yarn
$ react-native link "react-native-my-library"
6. 運(yùn)行
$ react-native run-android
7. 更新Library
每次更新插件代碼闪萄,都需要將項(xiàng)目的鏈接清除梧却,然后再重新鏈接。最好是清除緩存败去。為了避免說(shuō)你更新的原生代碼沒(méi)有生效的情況放航。
方法一:
進(jìn)入項(xiàng)目根目錄
$ react-native unlink "react-native-my-library"
$ yarn unlink "react-native-my-library"
進(jìn)入到插件目錄
$ yarn unlink
修改好插件代碼后,然后進(jìn)入插件根目錄圆裕,刪除node_modules
$ rm -rf node_modules
需要重新鏈接广鳍。
$ yarn
同上【引入插件 一】的說(shuō)明依次執(zhí)行荆几。
方法二:
進(jìn)入項(xiàng)目根目錄
$ react-native unlink "react-native-my-library"
修改好插件代碼后,然后進(jìn)入插件根目錄赊时,刪除node_modules
$ rm -rf node_modules
需要重新鏈接吨铸。
$ yarn
同上【引入插件 二】的說(shuō)明依次執(zhí)行。
配置中出現(xiàn)的問(wèn)題:
1. 找不到包引用
將VSCode和模擬器/命令行終端全部關(guān)掉祖秒,監(jiān)聽(tīng)端口8081的進(jìn)程全部關(guān)閉焊傅。然后重新打開,重新運(yùn)行狈涮。