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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值