zoontek / react-native-bootsplash

🚀 Show a splash screen during app startup. Hide it when you are ready.
MIT License
3.75k stars 259 forks source link

Stuck On Splash #83

Closed edoofx closed 4 years ago

edoofx commented 4 years ago

💻 My environment

🕵️‍♂️ Reproducing the issue

when im run with :

npx react-native run-android (DEBUG) : Running Well npx react-native run-android --variant=release : Running Well gradlew assembleRelease , install manual on device : Running Well

here we go, its time to upload to playstore gradlew bundleRelease (which is created AAB) and stuck (wont hide) at splash screen when im downloaded from playstore

🤞Solution

Do you know what needs to be done to address this issue? Ideally, provide a pull request with a fix.

zoontek commented 4 years ago

Please provide some code (JS)

edoofx commented 4 years ago

MainActivity.java

package com.appsimkomember;
import android.os.Bundle;
import com.facebook.react.ReactActivity;
import com.zoontek.rnbootsplash.RNBootSplash;

public class MainActivity extends ReactActivity {

  @Override
  protected String getMainComponentName() {
    return "appsimkomember";
  }
    @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    RNBootSplash.init(R.drawable.bootsplash, MainActivity.this); // <- display the generated bootsplash.xml drawable over our MainActivity
  }
}

AndroidManifest.xml


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.appsimkomember">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

  <application
    android:usesCleartextTraffic="true"
    android:name=".MainApplication"
    android:label="@string/app_name"
    android:icon="@mipmap/ic_launcher"
    android:roundIcon="@mipmap/ic_launcher"
    android:allowBackup="false"
    android:theme="@style/AppTheme">

    <activity
      android:name=".MainActivity"
      android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
      android:label="@string/app_name"
      android:windowSoftInputMode="adjustResize"
      android:exported="true"> <!-- add this line -->
      <!-- remove the intent-filter from MainActivity -->
    </activity>

    <!-- add the following lines -->
    <activity
      android:name="com.zoontek.rnbootsplash.RNBootSplashActivity"
      android:theme="@style/BootTheme"> <!-- apply the theme you created at step 3. -->
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>

  </application>

</manifest>

App.js

import React from 'react';
import {Container} from 'native-base';
import AuthLoading from './routes';
console.disableYellowBox = true;

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isReady: false,
    };
  }

  render() {
    return <AuthLoading />;
  }
}

AuthLoading.js

import React, {Component} from 'react';
import {
  ActivityIndicator,
  StatusBar,
  View,
  PermissionsAndroid,
  BackHandler,
  Alert,
} from 'react-native';
import ClearCache from 'react-native-clear-cache';
import RNBootSplash from 'react-native-bootsplash';
import * as Sentry from '@sentry/react-native';
Sentry.init({
  dsn: 'somedsnsentry',
});

export default class AuthLoading extends Component {
  async componentDidMount() {
    const {navigation} = this.props;
    this.focusListener = navigation.addListener('didFocus', () => {
      BackHandler.addEventListener('hardwareBackPress', this.onBackPress);
    });

    this.abc = navigation.addListener('didBlur', () => {
      BackHandler.removeEventListener('hardwareBackPress', this.onBackPress);
    });

    RNBootSplash.hide({duration: 250}); // fade

    ClearCache.clearAppCache(data => {});
    try {
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE,
        {
          title: 'INFO',
          message:
            'This apps require granted access for access some device info',
          buttonPositive: 'OK',
        },
      );
      if (granted === PermissionsAndroid.RESULTS.GRANTED) {
        this.props.navigation.replace('Home')
      } else {
        BackHandler.exitApp();
      }
    } catch (err) {
      console.warn(err);
    }
  }
  onBackPress = () => {
    Alert.alert(
      'Confirm',
      'Exit Apps ?',
      [{text: 'Cancel'}, {text: 'Yes', onPress: () => BackHandler.exitApp()}],
      {cancelable: true},
    );
    return true;
  };

  render() {
    return (
      <View>
        <ActivityIndicator />
        <StatusBar barStyle="default" />
      </View>
    );
  }
}

im confused because i cant trace error.. and some device install from playstore running well

thanks in advance @zoontek

edoofx commented 4 years ago

i think this issues because hermes enabled.

https://github.com/facebook/react-native/issues/26400

zoontek commented 4 years ago

@edoofx Did you tried https://github.com/facebook/react-native/issues/26400#issuecomment-539395814 ?

edoofx commented 4 years ago

yep, add this code

    configurations.all {
        resolutionStrategy {
            force "com.facebook.soloader:soloader:0.8.2"
        }
    }

now work like a charm.

thanks in advance for response @zoontek

afilp commented 4 years ago

@edoofx I still have this problem with RN 0.61.5, despite I have the following code:

// THE FOLLOWING CODE IS NEEDED TO GET FIREBASE ANDROID SDK WORKING
configurations.all {
  resolutionStrategy {
    force 'com.android.support:support-v4:27.1.0', 'com.facebook.soloader:soloader:0.8.0'
  }
}

react-native-bootsplash version: 2.2.4 react-native version: 0.61.5 Platform: android OS version: 10 Device: Mi 9T Pro Simulator: no

Will it help if I upgrade React Native to 0.62? If yes, should I remove the soloader requirement?

I do not know how to make this work, the splashscreen is stuck on load.

afilp commented 4 years ago

Hi, @zoontek I mistakenly referenced @edoofx , can you please see above?

It appears that I have the same problem which is not resolved. Am I missing something else?

Thank you!

zoontek commented 4 years ago

@afilp Where do you call RNBootsplash.hide ?

afilp commented 4 years ago

@zoontek Thanks!

We call it in Main.js which is called by index.js. Note that it used to work. We made several changes like react-navigation, etc.

Main.js

\\ Many imports here

class Main extends Component {
  constructor(props) {
    super(props);

    window.netInfoUnsubscribe = NetInfo.addEventListener(changeIsConnected);
  }

  componentDidMount() {
    // BackHandler.addEventListener('hardwareBackPress', this.handleBackPressed);
    if (BuildConfig.HAS_SPLASHSCREEN) {
      // do stuff while splash screen is shown
      // After having done stuff (such as async tasks) hide the splash screen
      const SplashScreen = require('react-native-bootsplash').default;
      setTimeout(() => {
        SplashScreen.hide({ duration: 200 });
      }, 1400);
    }

    AppState.addEventListener('change', state => {
      if (state === 'background') {
        stopBackgroundMusic(true);
      } else if (state === 'active') {
        startBackgroundMusic();
      }
    });
  }
\\ more code here...

index.js

import 'react-native-gesture-handler';
import { AppRegistry } from 'react-native';
import Main from './app/components/Main';
import { name as appName } from './app.json';
// import TrackPlayer from 'react-native-track-player';

const window = global;
window.jsBuildNumber = +require('./app.json').customFields.jsBuildNumber;

AppRegistry.registerComponent(appName, () => Main);

Note: I did debug the code and it reaches the hide part, but then nothing happens.

zoontek commented 4 years ago

Note that it used to work. We made several changes like react-navigation, etc.

It's probably a side effect then 😕 Can you reduce the amount of code by commenting some part to isolate the issue?

afilp commented 4 years ago

@zoontek I found the problem, sorry, I also had code from react-native-splashscreen. Now it shows the splashscreen.

I have a problem with immediate hide though: The splashscreen shows for too little time, it immediately hides when the JS is loaded. But I do have this, which seems to be ignored (note: I am using @react-navigation/native in case this matters:

      setTimeout(() => {
        SplashScreen.hide({ duration: 200 });
      }, 1400);
zoontek commented 4 years ago

@afilp You have to hide after initial render. Use componentDidMount or useEffect for that

afilp commented 4 years ago

@zoontek Thanks, I do this exactly as you say, in Main.js (see it in thread above: https://github.com/zoontek/react-native-bootsplash/issues/83#issuecomment-625342218)

zoontek commented 4 years ago

@afilp Does Main render your App entirely? Try listening to react-navigation events.

afilp commented 4 years ago

@zoontek I removed rendering of react-navigation just for test:

  render() {
    return <Text>Waiting...</Text>;

It looks a simple render, unfortunately the splash screen first hides and then "Waiting..." appears.

I even did this, to test show and the splashscreen does not show while waiting has been rendered:

  componentDidMount() {
    // BackHandler.addEventListener('hardwareBackPress', this.handleBackPressed);

    RNBootSplash.show({ duration: 200 });

    setTimeout(() => {
      RNBootSplash.hide({ duration: 200 });
      alert('hide');
    }, 3400);

Still the splashscreen does not show in JS, even with the .show method (it only shows before the JS starts). Note: I get the alert in timeout, so the code executes, I assume there is nothing to hide as the splash screen is already hidden when the JS starts.

afilp commented 4 years ago

I used to have react-native-splashscreen and I had all screens ready for mdpi, hdpi, etc. Now they seem to have padding around them (the purple color is the actual image), so they appear smaller.

See below, I deliberately used a different bootsplash_background color to show this "padding" around the purple image.

image

image

What causes this padding and how can we remove it?

zoontek commented 4 years ago

@afilp If your splash is just a logo, use the CLI to generate new assets without external padding.

afilp commented 4 years ago

@zoontek Good news, I managed to fix the problem with the .hide it now does hide.

I will also check your suggestion about the CLI, thanks a lot for your great support!

afilp commented 4 years ago

It did work! But the cli creates the proper files for the main flavor (Android), while I have many other flavors:

android\app\src\main\res\drawable\bootsplash.xml android\app\src\main\res\values\colors.xml

For example, I wanted to do this for flavor1 so that all related assets go to the /flavor1 folder instead:

android\app\src\flavor1\res\drawable\bootsplash.xml android\app\src\flavor1\res\values\colors.xml

Could another question be added in the CLI maybe? ("Android: Which flavor to generate images for? main")

zoontek commented 4 years ago

@afilp Not for now. We worked on using react-native CLI on the next major version, so our priority is to migrate and keep a rock-solid developer experience with it. After that, maybe we will add additional options.

afilp commented 4 years ago

The least I can do for your great support, is this "typo-fix" PR: https://github.com/zoontek/react-native-bootsplash/pull/109

Magesvarane-S commented 2 years ago

@zoontek Good news, I managed to fix the problem with the .hide it now does hide.

I will also check your suggestion about the CLI, thanks a lot for your great support!

@afilp May I know how please ?