React Native 添加启动屏教程,React Native启动白屏解决方案
目录
项目源码:react-native-splash-screen 问题描述:用React Native架构的无论是Android APP还是iOS APP,在启动时都出现白屏现象,时间大概1~3s(根据手机或模拟器的性能不同而不同)。 问题分析:为什么会产生白屏? React Native应用在启动时会将js bundle读取到内存中,并完成渲染。这期间由于js bundle还没有完成装载并渲染,所以界面显示的是白屏。 白屏给人的感觉很不友好,那有没有办法不显示白屏呢? 上文解释了:为什么React Native应用会在启动的时候显示一会白屏。既然知道了出现问题的原因,那么离解决问题也不远了。市场上大部分APP在启动的时候都会有个启动屏,启动屏对于用户是比较友好的,一来展示欢迎信息,二来显示一些产品信息或一些广告,启动页对于程序来说,是为程序完成初始化加载数据,做一些初始化工作的所保留的时间,启动屏等待的时间可长可短,具体根据业务而定。 下面我就教大家如何给React Native 应用添加启动屏,并解决启动白屏的问题。 Android启动白屏解决方案我们可以通过为React Native Android应用添加启动屏的方式,来解决启动白屏的问题。我在《React Native Android启动屏,启动白屏,闪现白屏》一文中介绍过一种为React Native Android应用添加启动屏的方法, 下面就向大家介绍另外一种为React Native Android应用添加启动屏的方案。 在《React Native Android启动屏,启动白屏,闪现白屏》一文中 小伙伴们肯定会说,对话框也不是全屏啊,主题也不一样啊,不过没关系,既然我们可以添加对话框,那么我们就可以修改对话框的样式来达到我们需要的效果。 要达到启动屏的效果,我们需要一个什么样效果的对话框呢?
上述是我们对这个对话框的基本需求,现在就让我们来实现这一需求: 第一步,创建一个对话框组件SplashScreen为满足上述需求,对话框组件需要提供下面两个方法: 1.显示对话框的方法: /** * 打开启动屏 */
public static void show(final Activity activity,final boolean fullScreen) {
if (activity == null) return;
mActivity = new WeakReference<Activity>(activity);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (!activity.isFinishing()) {
mSplashDialog = new Dialog(activity,fullScreen? R.style.SplashScreen_Fullscreen:R.style.SplashScreen_SplashTheme);
mSplashDialog.setContentView(R.layout.launch_screen);
mSplashDialog.setCancelable(false);
if (!mSplashDialog.isShowing()) {
mSplashDialog.show();
}
}
}
});
}
为了Activity被销毁的时候,持有的Activity能被及时的回收,这里我们通过 另外,因为在Android中所有的有关UI操作都必须在主线程,所有我们通过 上述代码中, 然后,我们可以在 @Override
protected void onCreate(Bundle savedInstanceState) {
SplashScreen.show(this,true);
super.onCreate(savedInstanceState);
}
2.关闭对话框的方法: /** * 关闭启动屏 */
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模块调用 第二步:向JS模块提供SplashScreen组件因为我们需要在js中调用 首先,创建一个 /** * SplashScreenModule * 出自:http://www.cboy.me * GitHub:https://github.com/crazycodeboy * Eamil:crazycodeboy@gmail.com */
public class SplashScreenModule extends ReactContextBaseJavaModule{
public SplashScreenModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "SplashScreen";
}
/** * 打开启动屏 */
@ReactMethod
public void show() {
SplashScreen.show(getCurrentActivity());
}
/** * 关闭启动屏 */
@ReactMethod
public void hide() {
SplashScreen.hide(getCurrentActivity());
}
}
其次,创建一个 /** * SplashScreenReactPackage * 出自:http://www.cboy.me * GitHub:https://github.com/crazycodeboy * Eamil:crazycodeboy@gmail.com */
public class SplashScreenReactPackage implements ReactPackage {
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new SplashScreenModule(reactContext));
return modules;
}
}
再次,在MainApplication中注册 @Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),new SplashScreenReactPackage()
);
}
准备工作,做好之后,下面我们就可以在JS中调用 第三步:在JS模块中控制启动屏的关闭创建一个名为SplashScreen的文件,加入下面代码。 /** * SplashScreen * 启动屏 * 出自:http://www.cboy.me * GitHub:https://github.com/crazycodeboy * Eamil:crazycodeboy@gmail.com * @flow */
'use strict';
import { NativeModules } from 'react-native';
module.exports = NativeModules.SplashScreen;
然后,我们可以在js中调用SplashScreen的hide()方法来关闭启动屏了。 componentDidMount() { SplashScreen.hide(); }
iOS启动白屏解决方案在iOS中,iOS支持为程序设置一个Launch Image或Launch Screen File来作为启动屏,当程序被打开的时候,首先显示的便是设置的这个启动屏了。 那么小伙伴会问了,这个启动屏幕什么时候会消失呢? 在
该方法返回一个 BOOL类型的值,当系统调用该方并返回值之后,标志着APP启动加载已经完成,系统会将启动屏给关掉。 所以如果我们控制了这个启动屏幕让它在js bundle加载并渲染完成之后再关闭不就解决了iOS 启动白屏了吗? 上面已经说到, 所以我们就想办法控制该方实行的时间。 第一步:创建一个名为SplashScreen的Object-C文件在SplashScreen.h文件中添加如下代码: //
// SplashScreen.h
// SplashScreen
// 出自:http://www.cboy.me
// GitHub:https://github.com/crazycodeboy
// Eamil:crazycodeboy@gmail.com
#import "RCTBridgeModule.h"
@interface SplashScreen : NSObject<RCTBridgeModule>
+ (void)show;
@end
在SplashScreen.m中添加如下代码: // SplashScreen
// 出自:http://www.cboy.me
// GitHub:https://github.com/crazycodeboy
// Eamil:crazycodeboy@gmail.com
#import "SplashScreen.h"
static bool waiting = true;
@implementation SplashScreen
- (dispatch_queue_t)methodQueue{
return dispatch_get_main_queue();
}
RCT_EXPORT_MODULE()
+ (void)show {
while (waiting) {
NSDate* later = [NSDate dateWithTimeIntervalSinceNow:0.1];
[[NSRunLoop mainRunLoop] runUntilDate:later];
}
}
RCT_EXPORT_METHOD(hide) {
dispatch_async(dispatch_get_main_queue(),^{
waiting = false;
});
}
@end
在上述代码中,我们通过 第二步:在JS模块中控制启动屏的关闭通过第一步我们已经向JS模块暴露了 开源库为了方便大家使用和解决React Native应用启动白屏的问题,我已经将上述方案做成React Native组件react-native-splash-screen, 最后既然来了,留下个喜欢再走吧,鼓励我继续创作(^_^)∠※ 如果喜欢我的文章,那就关注我的博客吧,让我们一起做朋友~~ 戳这里,加关注哦:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |