androidreact-nativeexpometro-bundler

react-native backgrounded development app loses connection to metro websocket after 5 seconds


My app https://github.com/NorseGaud/expo-testing does a simple AppState listener for "change" and console.logs the state when you background and then foreground the app.

When running metro with Using development build, I see that after 5 seconds of being backgrounded the log are saying the websocket is no longer available

2025-07-05 09:56:25.956 28692-28751 unknown:Re...gWebSocket app.maestro.expo.testing             E  Error occurred, shutting down websocket connection: Websocket exception
java.net.SocketException: Software caused connection abort
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:118)
    at java.net.SocketInputStream.read(SocketInputStream.java:173)
    at java.net.SocketInputStream.read(SocketInputStream.java:143)
    at okio.InputStreamSource.read(JvmOkio.kt:91)
    at okio.AsyncTimeout$source$1.read(AsyncTimeout.kt:129)
    at okio.RealBufferedSource.request(RealBufferedSource.kt:206)
    at okio.RealBufferedSource.require(RealBufferedSource.kt:199)
    at okio.RealBufferedSource.readByte(RealBufferedSource.kt:209)
    at okhttp3.internal.ws.WebSocketReader.readHeader(WebSocketReader.kt:119)
    at okhttp3.internal.ws.WebSocketReader.processNextFrame(WebSocketReader.kt:102)
    at okhttp3.internal.ws.RealWebSocket.loopReader(RealWebSocket.kt:293)
    at okhttp3.internal.ws.RealWebSocket$connect$1.onResponse(RealWebSocket.kt:195)
    at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1156)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:651)
    at java.lang.Thread.run(Thread.java:1119)

If I build a production build and run that on the emulator, it works just fine. What about the development build is causing the background for 5 seconds to break things?

Full log: https://gist.github.com/NorseGaud/c2e7207c765da0e81e5a267061c4301a


Solution

  • Any app that is backgrounded is quickly killed by the OS. That's what you're seeing there- the process is being killed by the Android OS because there is no foreground component, so no reason to keep the memory or other resources for it around. There is no work around or way to prevent this, this is the expected behavior of an Android app.

    (If you're curious how apps unbackground themselves like this- they don't. The OS will restart your app and launch the activity with a saved state bundle that it gives your app the opportunity to write before killing it. But unless you're almost instant in backgrounding and unbackgrounding, you're likely seeing a new instance of the application).