React Native實(shí)現(xiàn)js調(diào)用安卓原生代碼

1 問(wèn)題

   實(shí)現(xiàn)js調(diào)用安卓原始代碼,直接上代碼,簡(jiǎn)單粗暴

 
2 代碼實(shí)現(xiàn)

   1) 實(shí)現(xiàn)一個(gè)繼承ReactContextBaseJavaModule的類,MyToastModule.java文件如下

    public class MyToastModule extends ReactContextBaseJavaModule {
     
        public MyToastModule(ReactApplicationContext reactContext) {
            super(reactContext);
        }
     
        /**
         * getName方法返回一個(gè)字符串名字,就是js中的模塊名
         * 到時(shí)候我們寫(xiě)js的時(shí)候需要導(dǎo)入這個(gè)模塊,這里我用的是MyToast
         */
        @Override
        public String getName() {
            return "MyToast";
        }
     
        /**
         * 這是js調(diào)用的方法,需要使用注解@ReactMethod,返回類型必須為void
         */
        @ReactMethod
        public void show() {
            Toast.makeText(getReactApplicationContext(), "I am chenyu", Toast.LENGTH_SHORT).show();
        }
    }

 getName()方法返回一個(gè)字符串名字,就是js中的模塊名,到時(shí)候我們寫(xiě)js的時(shí)候需要導(dǎo)入這個(gè)模塊,這里我用的是MyToastshow()方法 show()方法是到時(shí)候js調(diào)用的方法,需要使用注解@ReactMethod,返回類型必須為void

 

 2) 實(shí)現(xiàn)繼承ReactPackage的一個(gè)類

   MyToastReactPackage.java 文件如下

    package com.pro_react;
     
    import com.facebook.react.ReactPackage;
    import com.facebook.react.bridge.NativeModule;
    import com.facebook.react.bridge.ReactApplicationContext;
    import com.facebook.react.uimanager.ViewManager;
     
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
     
    /**
     *
     */
     
    public class MyToastReactPackage implements ReactPackage {
     
        /**
         * 需要在應(yīng)用的Package類的createNativeModules方法中添加這個(gè)模塊。
         * 如果模塊沒(méi)有被注冊(cè),它也無(wú)法在JavaScript中被訪問(wèn)到。
         * @param reactContext
         * @return
         */
        @Override
        public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
     
            List<NativeModule> modules = new ArrayList<>();
            modules.add(new MyToastModule(reactContext));
            return modules;
        }
     
        @Override
        public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
            return Collections.emptyList();
        }
    }

這里的createNativeModules方法需要添加我之前寫(xiě)的MyToastModule模塊

 

  3 )  在MainApplication.java文加的getPackages方法中添加我自己的包,代碼如下

    package com.pro_react;
     
    import android.app.AppOpsManager;
    import android.app.Application;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.ApplicationInfo;
    import android.net.Uri;
    import android.os.Build;
    import android.util.Log;
     
    import com.facebook.react.ReactApplication;
    import com.facebook.react.ReactNativeHost;
    import com.facebook.react.ReactPackage;
    import com.facebook.react.shell.MainReactPackage;
    import com.facebook.soloader.SoLoader;
     
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.Arrays;
    import java.util.List;
     
    public class MainApplication extends Application implements ReactApplication {
      public static final String TAG = "MainApplication";
      private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
          return BuildConfig.DEBUG;
        }
     
        @Override
        protected List<ReactPackage> getPackages() {
          Log.i(TAG, "MainApplication getPackages");
          return Arrays.<ReactPackage>asList(
              new MainReactPackage(),
              new MyToastReactPackage()
          );
        }
     
        @Override
        protected String getJSMainModuleName() {
          return "index";
        }
      };
     
      @Override
      public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
      }
     
      @Override
      public void onCreate() {
        super.onCreate();
        Log.i(TAG, "MainApplication onCreate");
        SoLoader.init(this, /* native exopackage */ false);
      }
    }

  4) js模塊的編寫(xiě)

      js模塊要注意你需要加入這個(gè)

import {NativeModules} from 'react-native'

然后用變量保存安卓的模塊,也就是上面getName方法里面的返回值MyToast

var myAndroidToast = NativeModules.MyToast;

然后我是模擬,文本點(diǎn)擊觸發(fā)的調(diào)用原聲安卓的函數(shù),App.js文件如下

    /**
     * Sample React Native App
     * https://github.com/facebook/react-native
     *
     * @format
     * @flow
     */
     
    import React, {Component} from 'react';
    import {Platform, StyleSheet, Text, View, NativeModules} from 'react-native';
     
    const instructions = Platform.select({
      ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
      android:
        'Double tap R on your keyboard to reload,\n' +
        'Shake or press menu button for dev menu',
    });
    var myAndroidToast = NativeModules.MyToast;
    type Props = {};
    export default class App extends Component<Props> {
      render() {
        return (
          <View style={styles.container}>
            <Text onPress={()=> this._androidShowMsg()} style={styles.welcome}>Welcome to React Native!</Text>
            <Text style={styles.instructions}>To get started, edit App.js</Text>
            <Text style={styles.instructions}>{instructions}</Text>
          </View>
        );
      }
        /**
         *調(diào)用安卓原生代碼
         * @private
         */
        _androidShowMsg = () => {
           myAndroidToast.show();
        };     
     
    }
     
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
      },
      welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
      },
      instructions: {
        textAlign: 'center',
        color: '#333333',
        marginBottom: 5,
      },
    });


3 運(yùn)行結(jié)果

運(yùn)行之前要記得在項(xiàng)目的目錄下執(zhí)行下面的命令,它會(huì)在android的assets目錄下生成index.android.bundle文件,也就是安卓會(huì)加載這個(gè)js文件,這里也會(huì)起到編譯js作用,如果有語(yǔ)法錯(cuò)誤,這里控制臺(tái)會(huì)提示

react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res

然后執(zhí)行運(yùn)行項(xiàng)目命令

react-native run-android

點(diǎn)擊Welcome to React Native運(yùn)行結(jié)果如下

 


 

 










作者:chen.yu
深信服三年半工作經(jīng)驗(yàn),目前就職游戲廠商,希望能和大家交流和學(xué)習(xí),
微信公眾號(hào):編程入門(mén)到禿頭 或掃描下面二維碼
零基礎(chǔ)入門(mén)進(jìn)階人工智能(鏈接)