zoukankan      html  css  js  c++  java
  • React Native之原生模块的开发(Android)学习笔记

    目录

    1.为什么我们需要原生模块开发

    2.开发Android原生模块的主要流程

    3.原生模块开发实战

    1.为什么我们需要原生模块开发?

    我们在用RN开发App的时候,有时候需要用到一些原生模块,比如:分享、第三方登录等。在RN的官方文档是这样谈到的:

    “有时候App需要访问平台API,但在React Native可能还没有相应的模块。或者你需要复用一些Java代码,而不想用JavaScript再重新实现一遍;又或者你需要实现某些高性能的、多线程的代码,譬如图片处理、数据库、或者一些高级扩展等等。 ”

    2.开发Android原生模块的主要流程

    2.1 构建一个React Native Android原生模块的流程大致分为以下三大步:

    1. 编写相关的原生模块Java代码;
    2. 暴露接口与数据交互;
    3. 注册与导出React Native原生模块;

    2.1 使用React Native Android原生模块

    1. 在相应js组件中导入NativeModule;
    2. 使用对应暴露的接口方法;

    3.原生模块开发实战

    我们所要做的事情很简单,在RN组件中,点击一个按钮,触发原生模块中的我们所编写的事件,获取当前时间并显示

    3.1 使用Android Studio导入android项目

    如下图

    在android/app/src/main/java/下创建com.myNativeModule这样一个package(项目结构如下图)


     

    3.2 编写相关的原生模块Java代码

    在android/app/src/main/java/com/myNativeModule目录下新建一个TextModule.java。在这个类中,我们实现了具体的逻辑功能。

    package com.myNativeModule;
    
    import android.content.Context;
    import android.util.Log;
    import android.widget.Toast;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class TextModule {
    
        public void getTime(Context ctx) {
            SimpleDateFormat formatDate=new SimpleDateFormat("yyyy年MM月dd日  HH:mm:ss");
            Date date=new Date(System.currentTimeMillis());   //获取当前时间
            String s=formatDate.format(date);
    
            Log.e("HHH",s);
            Toast.makeText(ctx,s,Toast.LENGTH_SHORT).show();
        }
    
    }
    
    

     
    实现了获取当前时间功能后,我们接下来就要暴露给React Native,以供js调用。
     

    3.3 暴露接口与数据交互

    接下来我们就要向React Native暴露接口以及做一些数据交互部分的操作。为了暴露接口以及进行数据交互我们需要借助React Native的ReactContextBaseJavaModule 类。
     
    (在android/app/src/main/java/com/myNativeModule目录下新建一个MyNativeModule.java。)
     

    package com.myNativeModule;
    
    import android.content.Context;
    import android.widget.Toast;
    
    import com.facebook.react.bridge.ReactApplicationContext;
    import com.facebook.react.bridge.ReactContextBaseJavaModule;
    import com.facebook.react.bridge.ReactMethod;
    
    public class MyNativeModule extends ReactContextBaseJavaModule {
        private Context mContext;
    
        public MyNativeModule(ReactApplicationContext reactContext) {
            super(reactContext);
            mContext = reactContext;
        }
        
        // 重载了getName()方法,用来暴露我们原生模块的名字
        @Override  
        public String getName() {
            return "MyNativeModule";  // 返回的这个名字是必须的,是Native暴露给JS的名字
        }
    
        // 通过@ReactMethod注解来暴露接口,这样以来我们就可以在js文件中通过MyNativeModule.rnCallNative()来调用我们暴露给RN的接口了
        // 不能有返回值,因为被调用的原生代码是异步的,原生代码执行结束后只能通过回调函数或者发送消息给RN
        @ReactMethod 
        public void rnCallNative(String msg) {
            new TextModule().getTime(mContext);
        }
    }
    
    

    3.4 注册与导出React Native原生模块

    为了向React Native注册我们刚才创建的原生模块,我们需要实现ReactPackage,ReactPackage主要为注册原生模块所存在,只有已经向React Native注册的模块才能在js模块使用。
     
    (在android/app/src/main/java/com/myNativeModule目录下新建一个MyReactPackage.java。)
     

    package com.myNativeModule;
    
    import com.facebook.react.ReactPackage;
    import com.facebook.react.bridge.JavaScriptModule;
    import com.facebook.react.bridge.NativeModule;
    import com.facebook.react.bridge.ReactApplicationContext;
    import com.facebook.react.uimanager.ViewManager;
    import com.myNativeModule.MyNativeModule;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    public class MyReactPackage implements ReactPackage {
    
        @Override
        public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
    
            List<NativeModule> modules = new ArrayList<>();
            // 将我们创建的类添加到原生模块中
            modules.add(new MyNativeModule(reactContext));
            return modules;
        }
    
        public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
            return Collections.emptyList();
        }
    }
    
    

     
    在上述代码中,我们实现一个ReactPackage,接下来呢,我们还需要在android/app/src/main/java/com/nativetest/MainApplication.java中注册我们的MyReactPackage:
     

    @Override
        protected List<ReactPackage> getPackages() {
          return Arrays.<ReactPackage>asList(
              new MainReactPackage(),
              new MyReactPackage() // 在这里将我们刚才创建的MyReactPackage添加进来
          );
        }
    
    

    3.5 导出一个JS模块

    原生模块注册完成之后呢,我们接下来就需要为我们的原生模块导出一个js模块,这样做的目的是在实际的项目中,为了更好的可读性和可维护性以及更方便地使用它。
     
    在RN根目录的js/native/下创建一个native.js文件

    import { NativeModules } from 'react-native';
    export {
        MyNativeModule: NativeModules.MyNativeModule
    }
    
    

     
    接下来,我们就可以在其他地方通过下面的方式来使用所导出的这个模块了。
     

    import React, { Component } from 'react';
    import {  StyleSheet, View, Button } from 'react-native';
    import { MyNativeModule } from './native';
    
    type Props = {};
    export default class App extends Component<Props> {
    	render() {
    		return (
    			<View style={styles.container}>
    				<Button
    					onPress={this.call_button.bind(this)}
    					title="点击调用原生模块方法"
    				/>
    			</View >
    		); 	
    	}
    
    	call_button() {
    		MyNativeModule.rnCallNative('调用原生模块中的方法成功');
    	}
    }
    
    const styles = StyleSheet.create({
    	container: {
    		flex: 1,
    		justifyContent: 'center',
    		alignItems: 'center',
    		backgroundColor: '#F5FCFF',
    	}
    });
    
    

     
    测试结果如下:
     

    在上边的Demo中,主要是实现原生模块TestModule.java,然后我们在要被RN调用的方法中调用原生类中的方法。对于N多原生类都可以直接粘贴复制过来。这样就可以实现调用复杂方法实现强大功能了。

    Demo地址https://github.com/codeprolin/RN_Native_Android

  • 相关阅读:
    通过jsonp解决ajax的跨域请求问题
    为php安装redis扩展模块并测试
    浅谈使用 PHP 进行手机 APP 开发(API 接口开发)(转)
    touch事件记录
    jquery mobile 问题
    background总结,转自http://www.daqianduan.com/3302.html
    博客收集
    css3 border-radius 总结
    css3 box-shadow 总结
    angular 重置表单
  • 原文地址:https://www.cnblogs.com/fe-linjin/p/10678519.html
Copyright © 2011-2022 走看看