ReactNative学习笔记——调用原生模块(Android)

Posted mictoy_朱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ReactNative学习笔记——调用原生模块(Android)相关的知识,希望对你有一定的参考价值。

crazyboycode/react-native-splash-screen为例,给一个RN应用添加一个应用启动屏,以掩盖app启动白屏的问题。
说明:该模块应用场景是在app启动时,由于RN渲染需要时间,因手机性能的问题可能会导致应用2到3秒的白屏时间。因此为了解决该问题,我们给RN应用添加一个Native启动屏,以掩盖这种因启动白屏而引起的不友好的用户交互。

准备工作

开发环境:window10
开发工具:android Studio、WenStorm

开发步骤

  • 用WebStorm打开一个RN工程,并用Android Studio打开该工程下对应的android项目
  • 创建原生模块SplashScreen,此模块为RN中将要调用到的原生模块
package com.myunionpaydemo;

import android.app.Activity;
import android.app.Dialog;

import java.lang.ref.WeakReference;

public class SplashScreen 
    private static Dialog mSplashDialog;
    private static WeakReference<Activity> mActivity;

    public static void show(final Activity activity, final boolean fullScreen) 
        if (activity != null) 
            mActivity=new WeakReference<>(activity);
            activity.runOnUiThread(new Runnable() 
                @Override
                public void run() 
                    if (!activity.isFinishing()) 
                        mSplashDialog = new Dialog(activity);
                        mSplashDialog.setContentView(R.layout.layout_splash_screen);
                        mSplashDialog.setCancelable(false);
                        if (!mSplashDialog.isShowing()) 
                            mSplashDialog.show();
                        
                    
                
            );
        
    

    /**
     * 关闭启动屏
     */
    public static void hide(Activity activity) 
        if (activity == null)
            activity = mActivity.get();

        if (activity == null) return;

        activity.runOnUiThread(new Runnable() 
            @Override
            public void run() 
                if (mSplashDialog != null && mSplashDialog.isShowing()) 
                    mSplashDialog.dismiss();
                
            
        );
    

  • 向JS模块提供SplashScreen模块
    JS不能直接调用Java,所以我们需要为他们搭建一个桥梁Native Modules
    首先,创建一个ReactContextBaseJavaModule类型的类,供JS调用
package com.myunionpaydemo;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

public class SplashScreenModule extends ReactContextBaseJavaModule 

    public SplashScreenModule(ReactApplicationContext reactContext) 
        super(reactContext);
    

    @Override
    public String getName() 
        return "SplashScreen";
    

    /**打开启动屏*/
    @ReactMethod
    public void show()
        SplashScreen.show(getCurrentActivity(),true);
    

    /**关闭启动屏*/
    @ReactMethod
    public void hide()
        SplashScreen.hide(getCurrentActivity());
    

注意,这里的show()hide()是最终在RN的JS代码中调用的方法,因此需要添加@ReactMethod注解

  • MainApplication中注册SplashScreenModule模块
@Override
protected List<ReactPackage> getPackages() 
    return Arrays.<ReactPackage>asList(
        new MainReactPackage(),
        new SplashScreenReactPackage()
     );
  • 在RN的JS模块中调用原生模块
    我们可以在RN中调用我们编写好的原生模块了。
    现在转移到WebStorm里进行调用原生模块的相应工作。
    1.创建一个名为SplashScreen的js文件,添加代码如下:
import NativeModules from 'react-native'
export default NativeModules.SplashScreen;

2.在RN应用首页调用相应的方法(此处根据示例要求,我们在componentDidMount方法调用hide()方法,即首页画面已经渲染完成,可以关闭加载启动屏)

import SplashScreen from "./SplashScreen";
...
//渲染之前调用原生模块Dialog遮盖白屏
componentWillMount()
        SplashScreen.show();
    

componentDidMount()
        SplashScreen.hide();
    
render() 
        return (
            <View style=styles.container>
                <Text 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>
                this.getLastView()
            </View>
        );
    

    getLastView()
        let i=500000000;
        //添加循环,模拟复杂页面渲染时的耗时时间
        while (i)
            i--;
        
        return(<Text style=styles.welcome>
            Welcome to React Native!
        </Text>);
    
...

至此,调用原生模块的工作就全部完成,最后运行看下效果:

短暂的启动屏一闪而过,效果还不是很好,还是会有短暂的白屏,不过调用原生模块的功能成功实现了Y(·_·)Y

参考资料
1. crazycodeboy/react-native-splash-screen
2. React-Native-启动白屏问题解决方案,教程

Demo 地址:GetNativeModule

以上是关于ReactNative学习笔记——调用原生模块(Android)的主要内容,如果未能解决你的问题,请参考以下文章

React Native学习笔记:集成到现有原生应用

Flutter笔记-调用原生IOS高德地图sdk

ReactNative-JS 调用原生方法实例代码(转载)

React Native在原生和React Native间通信

H5调用Android和ios原生方法(react)

封装iOS原生资源库link到项目供ReactNative使用