React Native For Android學(xué)習(xí)之路-創(chuàng)建自定義原生模塊

前言

React Native一經(jīng)推出就非常火爆,吸引了國內(nèi)外的開發(fā)者的注意,好處不必多說,該文章以筆記的形式來記錄自己的學(xué)習(xí)歷程。
本文記錄了基于官方文檔來創(chuàng)建一個(gè)Android平臺(tái)的自定義的原生模塊(NativeModule)。

準(zhǔn)備

需要提前準(zhǔn)備好一個(gè)ReactNative項(xiàng)目,同時(shí)App與服務(wù)器端鏈接良好,可以正常"Reload JS"

關(guān)于本例

本例代碼將實(shí)現(xiàn)一個(gè)Toast的Native(React官方已提供該模塊),借此來學(xué)習(xí)創(chuàng)建一個(gè)自定義NativeModule(原生組件)的方法。

效果圖如下:

react_native_crate_native_module.png

編寫模塊

首先編寫一個(gè)自定義模塊的類,該類需要繼承ReactContextBaseJavaModule, 并需要實(shí)現(xiàn)getName()方法返回一個(gè)模塊名稱,在本實(shí)例中,該自定義模塊將實(shí)現(xiàn)Android的Toast功能,所以定義了一個(gè)show()方法,并加上了ReactMethod注解,這個(gè)注解可以將show(String msg, int duration)中的Java參數(shù)類型映射成Js中對應(yīng)的數(shù)據(jù)類型,具體映射關(guān)系如下:

Boolean -> Bool
Integer -> Number
Double -> Number
Float -> Number
String -> String
Callback -> function
ReadableMap -> Object
ReadableArray -> Array

代碼本身很簡單,具體可以看注釋

源代碼

public class ToastAndroidModule extends ReactContextBaseJavaModule {

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

    public ToastAndroidModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    /**
     * 定義模塊名稱
     * @return
     */
    @Override
    public String getName() {
        return "MyToastAndroid";
    }

    /**
     * 可以設(shè)置一些常量,能夠在js層調(diào)用,本例中在JS代碼中調(diào)用如"MyToastAndroid.LONG"
     * @return
     */
    @Nullable
    @Override
    public Map<String, Object> getConstants() {
        final Map<String, Object> constants = new HashMap<>(2);
        constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
        constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
        return constants;
    }

    /**
     * 自定義方法,通過ReactMethod注解可以把一些Java常量類型映射成js類型
     * @param msg
     * @param duration
     */
    @ReactMethod
    public void show(String msg, int duration) {
        Toast.makeText(getReactApplicationContext(), msg, duration).show();
    }
}

注冊模塊

在目前0.20版本上,我們自定義原生模塊(NativeModule)是需要注冊才能生效的,所以編寫好模塊之后需要重新打包安裝到手機(jī)上。

編寫Package

注冊模塊首先可以先寫個(gè)自定義的Package,顧名思義,就是一個(gè)可以包含你自己寫的模塊的一個(gè)包,然后把包在MainActivity(本例中的類)中注冊下,通過已有工程引入React組件的可以根據(jù)實(shí)際情況修改,也不難。
本例中新建一個(gè)MyPackage類,通過實(shí)現(xiàn)ReactPackage的三個(gè)接口來完成模塊的綁定,其中createNativeModules方法是我們本例需要用到的,其他兩個(gè)之后再說,要注意三個(gè)方法均不能返回null類型,不需要用到的請傳入一個(gè)空集合!

源代碼

public class MyPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>(1);
        // 將我們自定義模塊添加一個(gè)集合中,這樣React組件就會(huì)在合適的時(shí)機(jī)將我們引用的模塊加載進(jìn)去,這樣后面才能愉快地玩耍~
        modules.add(new ToastAndroidModule(reactContext));
        return modules;
    }

    @Override
    public List<Class<? extends JavaScriptModule>> createJSModules() {
        //現(xiàn)在不需要用到,不要傳null,否則報(bào)錯(cuò)
        return Collections.emptyList();
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        //現(xiàn)在不需要用到,不要傳null,否則報(bào)錯(cuò)
        return Collections.emptyList();
    }
}

注冊Package

寫好Package之后,就可以愉快將Package加入到MainActivity(本例)類里,方法很簡單,直接貼部分源代碼

public class MainActivity extends ReactActivity {

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return "AwesomeProject";
    }

    /**
     * Returns whether dev mode should be enabled.
     * This enables e.g. the dev menu.
     */
    @Override
    protected boolean getUseDeveloperSupport() {
        return BuildConfig.DEBUG;
    }

    /**
     * A list of packages used by the app. If the app uses additional views
     * or modules besides the default ones, add more packages here.
     */
    @Override
    protected List<ReactPackage> getPackages() {
        return Arrays.<ReactPackage>asList(
                new MainReactPackage(),
                //加入我們自己寫的Package
                new MyPackage()
        );
    }
}

編譯打包&安裝到手機(jī)

由于我們修改了Android代碼,因此需要重新編譯打包,并安裝到我們的手機(jī)中,此步驟省略。

編寫JS

JS編寫也清晰了然,可以直接查看源碼。

源代碼

import React, {
    AppRegistry,
    Component,
    StyleSheet,
    Text,
    View,
    NativeModules
} from 'react-native';

class AwesomeProject extends Component {
    constructor(props) {
        super(props);
    }

    componentDidMount() {
        var MyToastAndroid = NativeModules.MyToastAndroid;
        MyToastAndroid.show('This is from MyToastAndroid Native Module', MyToastAndroid.LONG)
    }

    render() {
        return (
            <View style={styles.container}>
                <Text>
                    NativeModule Test by BogerChan
                </Text>
            </View>
        );
    }
};

var styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },
});

AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,656評論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內(nèi)容