react-native 啟動白屏問題解決方案


當 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 方法 發出通知 關閉占位圖

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM