Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Persisting SplashScreen until react native bundle is loaded in android

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.

like image 204
Ilja Avatar asked Mar 30 '18 15:03

Ilja


People also ask

How to show splash screen in React Native?

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.

What is a splash screen React Native?

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 .

Why React Native screens?

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.


1 Answers

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

  1. MainApplication (assign mReactNativeHost) ->
  2. ReactNativeHost.createReactInstanceManager (copy original method but call ReactInstanceManagerBuilder.setJSBundleLoader) ->
  3. JSBundleLoader (wrap original JSBundleLoader.createAssetLoader into custom subclass, which would call inner loader in loadScript and then also call CatalystInstanceImpl.callFunction) ->
  4. 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.

like image 148
Serge Seredenko Avatar answered Sep 21 '22 15:09

Serge Seredenko