I followed android guide in this article How to Add a Splash Screen to a React Native App
And got to the point where I have my SplashScreen activity launching before my main activity i.e. while android app is inflating.
So far so good, but there is flicker of white that is caused by react native js bundle loading that I'd like to remove. Article suggests using react-native-splash-screen
library, however I'd like to keep my dependencies to a minimum.
React native documentation has this Pro Tip that essentially achieves what I am looking for, but in iOS (it keeps showing splash screen while bundle is not loaded). I am trying to figure out how I would do something similar in native java for android, but so far no luck.
Building a React Native splash screen To begin, follow the steps below. Run each command in your terminal (on mac) or command prompt (on Windows): npm i to install all the dependencies that are included in the starter file. npm i react-native-splash-screen --save to install the RNSplashscreen package.
A splash screen is the first screen the users see after tapping the app icon. It's typically a simple screen with your app logo in the center and goes away once the app is ready to launch. There are two popular packages for adding a splash screen to your app. Namely react-native-splash-screen and expo-splash-screen .
react-native-screens provides native primitives to represent screens instead of plain <View> components in order to better take advantage of operating system behavior and optimizations around screens. This capability is used by library authors and unlikely to be used directly by most app developers.
Here a way to do it when content is added by React:
=== MainActivity.java ===
import com.facebook.react.*;
import android.content.Context;
import android.app.Activity;
import android.util.Log;
import android.view.View;
public class MainActivity extends ReactActivity {
class CustomReactActivityDelegate extends ReactActivityDelegate {
class CustomReactRootView extends ReactRootView {
public CustomReactRootView(Context context) {
super(context);
}
@Override
public void onViewAdded(View child) {
super.onViewAdded(child);
Log.d("React views started to appear", "Static js code has already run");
}
}
private Activity currentActivity;
public CustomReactActivityDelegate(Activity activity, String mainComponentName) {
super(activity, mainComponentName);
currentActivity = activity;
}
protected ReactRootView createRootView() {
return new CustomReactRootView(currentActivity);
}
}
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new CustomReactActivityDelegate(this, getMainComponentName());
}
...
}
As you can see, the idea is to override stuff to hook into needed moment.
You could see other stuff to hook into in those classes, but in general react loads bundle asynchronously with jni functions, so I am not sure there's much to do there. You could override a chain
MainApplication
(assign mReactNativeHost
) ->ReactNativeHost.createReactInstanceManager
(copy original method but call ReactInstanceManagerBuilder.setJSBundleLoader
) ->JSBundleLoader
(wrap original JSBundleLoader.createAssetLoader
into custom subclass, which would call inner loader in loadScript
and then also call CatalystInstanceImpl.callFunction
) ->CatalystInstanceImpl.PendingJSCall
to just run what you need to run in there.In other words, it's horrible and still React does not guarantee that PendingJSCall
won't be run before bundle loads.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With