Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 51|回复: 0

react-native 启动白屏问题解决方案

[复制链接]
  • TA的每日心情
    奋斗
    昨天 15:16
  • 签到天数: 187 天

    [LV.7]常住居民III

    1473

    主题

    1531

    帖子

    8万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    84758
    发表于 2021-9-3 16:03:55 | 显示全部楼层 |阅读模式

    当 react-native 的 bundle 包过大的时候,可能会出现加载完启动图之后会有一个白屏出现 ,然后才是你的 APP 的第一个页面, 这是由于在加载完启动图之后,也就是执行完 applicationDidFinishLaunch(){}的时候,React Native应用在启动时会将js bundle读取到内存中,并完成渲染。这期间由于js bundle还没有完成装载并渲染,所以界面显示的是白屏。

    如何优化这个问题?

    1>> 可以分包 但是很麻烦

    2>>在启动图结束后, js bundle 解析完之前, 制造一个假象, 也就是欺骗用户, 让用户以为还在展示 launchImage 实际上 launchImage 早已展示完了, 在 native 放一张和启动图一样的图片

    具体步骤如下:

    (1) - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;  // 启动图结束调用的方法 在这里设置一个跟启动图一样的占位图

    (2)componentDidMount() { }  // js bundle里的第一个页面的组件加载的方法 也就是 js解析完成之后将会第一个调用的方法, 在这个方法里移除占位图 具体可以利用通知 在这里发送关闭的通知 收到通知后 隐藏占位图

    具体实现:

    1>> 新建一个 nativeMoudle  SplashScreen类用来发送移除占位图的通知

    #import <Foundation/Foundation.h>

    #import "RCTBridgeModule.h"

    @interface SplashScreen : NSObject<RCTBridgeModule>

    @end

     

    .m文件 暴露一个供 js 调用的方法 js bundle 解析完成之后 调用该方法 即可发送关闭的通知 native 收到通知即可移除占位图

    #import "SplashScreen.h"

    @implementation SplashScreen RCT_EXPORT_MODULE();

    RCT_EXPORT_METHOD(close){

      [[NSNotificationCenter defaultCenter] postNotificationName:@"Notification_CLOSE_SPLASH_SCREEN" object:nil];

    }

    @end

    -------native 中 AppDelegate.m-----------

    @interface AppDelegate (){

      UIImageView *splashImage;

    }

    @end

    @implementation AppDelegate

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

      // 添加监听者 监听关闭占位图的通知

       [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(closeSplashImage) name:"Notification_CLOSE_SPLASH_SCREEN" object:nil];

       XXXXXXXXXXX

     

       [self autoSplashScreen];//写在 return YES 之前,其他代码之后

       return YES;

    }

    -(void)autoSplashScreen {

       if (!splashImage) {

        splashImage = [[UIImageView alloc]initWithFrame:[UIScreen mainScreen].bounds];

      }

      if (IPHONESCREEN3p5) {

         [splashImage setImage:[UIImage imageNamed:@"launch4"]];

      }else if (IPHONESCREEN4){

         [splashImage setImage:[UIImage imageNamed:@"launch5"]];

       }else if (IPHONESCREEN4p7){

        [splashImage setImage:[UIImage imageNamed:@"launch6"]];

      }else if (IPHONESCREEN5p5){

         [splashImage setImage:[UIImage imageNamed:@"launch7"]];

       }

       [self.window addSubview:splashImage];  // 最后在添加到父视图上 保证不会被遮盖

    }

    // 收到通知之后  动画将透明度变为0 然后移除 即可显示 js bundle 里的第一个页面

     

    -(void)closeSplashImage {

      dispatch_sync(dispatch_get_main_queue(), ^{

         [UIView animateWithDuration:0.5 animations:^{

          splashImage.alpha = 0;

      } completion:^(BOOL finished){

        [splashImage removeFromSuperview];

    }]; }); }

    最后一步

    if (Platform.OS === 'ios') {

      NativeModules.SplashScreen.close();

    };

    在 js第一个页面里选择合适的时机 调用 nativeMoudle 的 close 方法 发出通知 关闭占位图

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2021-12-4 12:17 , Processed in 0.064966 second(s), 27 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表