When trying to start my app on an Android device, the splash screen shows and then never transitions to the tabs/screen.
I followed the setup instructions for Android, it's not the first time I've done so and for some reason the Android app hangs completely on the splash screen. Here are my adjusted native files. I hope one of you can spot some dumb mistake I've made. Note that the entry point is index.js
and I've registered the screen(s) and run Nativation.startTabBasedApp/startSingleScreenApp
(tried both). If you need to see that let me know. It seems to be down to the native code. I've eliminated all extraneous startup JS and the issue persists.
android/settings.gradle:
rootProject.name = 'MyApp'
include ':react-native-navigation'
project(':react-native-navigation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-navigation/android/app/')
include ':app'
android/app/build.gradle:
android {
compileSdkVersion 25
buildToolsVersion "25.0.1"
...
dependencies {
compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:23.0.1"
compile "com.facebook.react:react-native:+" // From node_modules
compile project(':react-native-navigation')
}
MainActivity:
package com.ma.android;
import android.view.View;
import android.widget.ImageView;
import com.facebook.react.ReactActivity;
import com.reactnativenavigation.controllers.SplashActivity;
public class MainActivity extends SplashActivity {
@Override
public View createSplashLayout() {
ImageView splash = new ImageView(this);
splash.setImageResource(R.drawable.screen);
splash.setScaleType(ImageView.ScaleType.CENTER_CROP);
return splash;
}
}
MainApplication:
package com.myApp.android;
import com.facebook.react.ReactPackage;
import java.util.Arrays;
import java.util.List;
import com.reactnativenavigation.NavigationApplication;
public class MainApplication extends NavigationApplication {
@Override
public boolean isDebug() {
// Make sure you are using BuildConfig from your own application
return BuildConfig.DEBUG;
}
protected List<ReactPackage> getPackages() {
// Add additional packages you require here
// No need to add RnnPackage and MainReactPackage
return Arrays.<ReactPackage>asList();
}
@Override
public List<ReactPackage> createAdditionalReactPackages() {
return getPackages();
}
@Override
public String getJSMainModuleName() {
return "index";
}
}
AndroidManifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myApp.android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application
android:name=".MainApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:allowBackup="false"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
</manifest>
+1
I solve this by add icon like example. Cheer :)
Hey there, This usually means Navigation.startSingleScreenApp
or Navigation.startTabBasedApp
weren't called. Did you verify startApp was called?
@guyca It's been hard to verify as I cannot get debug started. I can share with you my calls to do so. I believe it has to be something in the Android specific platform code as it works fine on iOS. That may not be the case but usually if it is a JS error you get a red box or at least can start up debugging. Also I've tested by stripping out as much as possible from the JS code. Regardless, here's the JS side of things. Thank you for your help. I hope this is the appropriate venue for this.
./index.js:
require('./app/index')
./app/index.mjs:
import { AsyncStorage } from 'react-native'
import { Navigation } from 'react-native-navigation'
import I18n from 'react-native-i18n'
import { CachePersistor } from 'apollo-cache-persist'
import registerScreens from './screens'
import { getNavIcons, navIcons } from './resources/fonts'
import locales from './resources/locales'
import { ScreenListener } from './utils'
import appConfig from './config.json'
import client from './apollo'
import cache from './apollo/cache'
const navigatorStyle = {
navBarHidden: true,
drawUnderTabBar: false,
tabBarHidden: false,
statusBarHidden: false,
statusBarHideWithNavBar: false,
screenBackgroundColor: 'white',
orientation: 'portrait',
disabledBackGesture: false,
}
const tabsStyle = {
tabBarHidden: false,
tabBarButtonColor: 'blue',
tabBarBackgroundColor: 'white',
tabBarTranslucent: false,
tabBarTextFontFamily: 'System',
tabBarLabelColor: 'blue',
forceTitlesDisplay: true,
tabBarSelectedButtonColor: 'blue',
tabBarSelectedLabelColor: 'blue',
hideBackButtonTitle: true,
};
(async () => {
I18n.fallbacks = true
I18n.translations = locales
registerScreens(client)
const persistor = new CachePersistor({
cache,
storage: AsyncStorage,
key: 'shop-persist',
})
await persistor.restore()
await getNavIcons(appConfig.navigationIcons)
new ScreenListener().register()
Navigation.startTabBasedApp({
tabs: [
{
label: 'Home',
screen: 'shop.Home',
icon: navIcons.home,
navigatorStyle,
testID: 'HomeTab',
},
{
label: 'Account',
screen: 'shop.Account',
icon: navIcons.person,
navigatorStyle,
testID: 'AccountTab',
},
{
label: 'Search',
screen: 'shop.Search',
icon: navIcons.search,
navigatorStyle,
testID: 'SearchTab',
},
{
label: 'Stores',
screen: 'shop.Stores',
icon: navIcons.store,
navigatorStyle,
testID: 'StoresTab',
},
{
label: 'Shop Local',
screen: 'shop.ShopLocal',
icon: navIcons['location-on'],
navigatorStyle,
testID: 'ShopLocalTab',
},
],
tabsStyle,
appStyle: Object.assign({}, tabsStyle),
})
})()
Update: this has nothing to do with the posted code snippets apparently. It is an environmental issue with my machine somehow. A co-worker was able to run the app just fine on the same branch/phone as I and had no issues. This is the command we're using to run our app:
react-native run-android --no-packager && clear & make start
For me what happens is that the splash activity loads - and the main index.js
is loaded only when leaving the activity by pressing the home button.
Then returning to the app shows the splash activity for a split second - and the app is moved to background immediately.
Then returning to the app again - shows the app, and isAppLaunched
gets resolved.
I put logs in the index.js
, to make sure, and I can clearly see that it's not loaded until you leave the app.
We figured out it was the use of the power operator, **
. I don't understand exactly why or how, but changing this out with Math.pow
fixed it. I can't imagine that's not being transpiled.
I can reproduce this on android:
now splash screen is stuck, and the only way to fix this is to clear application data to exit debug mode
Edit:
I could fix it like this:
note: if you press back button to close stuck splash screen then clear recent application then this method of lock/unlock screen will not work.
I am facing the same issue. When I run my app on android device splash screen got stuck and nothing happens after that. (Working fine on android simulator and iOS device and simulator both.) I have followed the steps as described in the document.
I am using
"react-native": "0.57.3",
"react-native-navigation": "^1.1.489"
MainActivity.java
public class MainActivity extends SplashActivity {
@Override
public LinearLayout createSplashLayout() {
LinearLayout splash = new LinearLayout(this);
Drawable launch_screen_bitmap = ContextCompat.getDrawable(getApplicationContext(),R.drawable.background_splash);
splash.setBackground(launch_screen_bitmap);
return splash;
}
}
AndroidMainfest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.truckerapp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application
android:name=".MainApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:allowBackup="false"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
</manifest>
App.js
Navigation.startSingleScreenApp({
screen: {
screen: "myApp.WelcomeScreen",
title: "Welcome"
}
});
And after pressing the hardware back button, the app force closes and then unable to open it again.
Can anybody help me in this?
@Yousefjb how to clear application data to exit from debug mode?
@adirzoari you have to go to Apps settings in your device and find your app then press clear storage.
I clean storage. still have issue. what can i do?
I also had this issue when there was a runtime exception at index.js
make sure there are no exceptions before startSingleScreenApp
or before the first component render
I don't see any startSingleScreenApp on my app. I don't use react-native-navigation of wix.
you don't ?
this is an issue for react-native-navigation, if you use react-navigation then check their issue tracker.
@Yousefjb I found the issue. I removed console.log and it solve my issue.
I did console.log for this and it was hard for the app.
it looks like wrapping Navigation.setRoot
with
Navigation.events().registerAppLaunchedListener(() => {
Navigation.setRoot({
root: {
component: {
name: "navigation.playground.WelcomeScreen"
}
}
});
});
helps, but I'm not really sure. It still looks like it freezes for a while and then in a 15 sec started.
@alburdette619, can you please describe when we need to use Math.pow
? I have the same app freeze on my RN app when back btn is pressed
Hi there, I've encountered the same issue, any solution ?
A few people above mentioned this happening specifically when exiting their app using the back button. I ran into this bug too and did a bit of research to work out what is going on – perhaps this will be helpful:
I was finding that if I closed my app by pressing the home button, my app would reopen correctly when I went back into it. However, if I closed the app by pressing the back button from a top-level activity, when I reopened the app it would hang on the splash screen forever.
I did some research and basically: when you exit an app with the back button, the top-level activity on Android gets destroyed but the application (and hence JS thread) doesn't. I think this is standard Android behaviour rather than anything to do with RNN. Here's a list of the three main ways you can close an app, and what happens in each case:
So when you reopen an app after scenario 2, although it feels like the whole app is starting up from scratch, it actually isn't.
The issue for me was because my main index.js
file looked like this:
Navigation.setRoot(opts)
The problem with that is that Navigation.setRoot()
is the function that actually triggers the creation of activities. This means reopening the app after scenarios 1 and 3 worked fine for me (in scenario 1 the activity was never destroyed, and in scenario 3 the JS thread got restarted so setRoot
got called again), but reopening after scenario 2 made the app get stuck.
So the solution for me was, as previous people have said, to do this instead:
Navigation.events().registerAppLaunchedListener(() => {
Navigation.setRoot(opts)
})
as registerAppLaunchedListener
gets triggered when the app is re-opened after being closed with the back button!
I notice that the docs do specify this as the correct pattern (see here), but I set this app up 2.5 years ago so potentially the API was a bit different for the 1.x version I was on back then or maybe the docs weren't as good as they are now.
Hope that helps clarify things a bit. Interested to know if I've misunderstood anything.
Ahhh, thanks a million for the detailed explanation @bdrobinson! I'd been stuck on this one for months.
In our case, we actually have an abstraction around the Wix Navigation
API which exposes the registerAppLaunchedListener
as an observable. We'd always been using that before doing setRoot
, so I didn't really consider that would be the issue.
But the mistake we made was that our abstraction assumed the event would only ever need to be emitted once! In the second scenario you listed above - that assumption was clearly incorrect. There may indeed be times where JavaScript is already running and yet the app is "starting up" again.
Most helpful comment
A few people above mentioned this happening specifically when exiting their app using the back button. I ran into this bug too and did a bit of research to work out what is going on – perhaps this will be helpful:
I was finding that if I closed my app by pressing the home button, my app would reopen correctly when I went back into it. However, if I closed the app by pressing the back button from a top-level activity, when I reopened the app it would hang on the splash screen forever.
Android lifecycles
I did some research and basically: when you exit an app with the back button, the top-level activity on Android gets destroyed but the application (and hence JS thread) doesn't. I think this is standard Android behaviour rather than anything to do with RNN. Here's a list of the three main ways you can close an app, and what happens in each case:
So when you reopen an app after scenario 2, although it feels like the whole app is starting up from scratch, it actually isn't.
The issue
The issue for me was because my main
index.js
file looked like this:The problem with that is that
Navigation.setRoot()
is the function that actually triggers the creation of activities. This means reopening the app after scenarios 1 and 3 worked fine for me (in scenario 1 the activity was never destroyed, and in scenario 3 the JS thread got restarted sosetRoot
got called again), but reopening after scenario 2 made the app get stuck.So the solution for me was, as previous people have said, to do this instead:
as
registerAppLaunchedListener
gets triggered when the app is re-opened after being closed with the back button!I notice that the docs do specify this as the correct pattern (see here), but I set this app up 2.5 years ago so potentially the API was a bit different for the 1.x version I was on back then or maybe the docs weren't as good as they are now.
Hope that helps clarify things a bit. Interested to know if I've misunderstood anything.