facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
119.13k stars 24.32k forks source link

Android TransactionTooLargeException #19458

Closed dluksza closed 4 years ago

dluksza commented 6 years ago

Environment

Environment: OS: macOS High Sierra 10.13.4 Node: 10.2.1 Yarn: 1.7.0 npm: 5.6.0 Watchman: 4.9.0 Xcode: Xcode 9.3.1 Build version 9E501 Android Studio: 3.1 AI-173.4720617

Packages: (wanted => installed) react: 16.4.0 => 16.4.0 react-native: ^0.55.4 => 0.55.4

Steps to Reproduce

I was unable to find reproduction steps for this error. I'm using crashlytics to collect informations about app crashes, that's how I found out about this one.

I'm also aware about https://github.com/facebook/react-native/issues/15429, and did updated compileSdkVersion and targetSdkVersion to 26, then to 27 and still see this exception reported.

For the latest version it mainly happens on Android 7 and 8 and Samsung and Motorola devices.

Here is a thread dump for one particular instance: org.luksza.habitchallenge_issue_14_crash_5B08A3070387000105A3FE70635B0C4C_DNE_1_v2.txt

Expected Behavior

Application should not crash.

Actual Behavior

Application crashes

L-Yeiser commented 6 years ago

We are also seeing this in our crash analytics.

stale[bot] commented 6 years ago

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as "For Discussion" or "Good first issue" and I will leave it open. Thank you for your contributions.

dluksza commented 6 years ago

The issue still persist but it seams to occur less frequently

littlehome-eugene commented 6 years ago

We are having the same issue. @dluksza did you do anything to make it occur less frequently?

dluksza commented 6 years ago

@littlehome-eugene, I did nothing, apart from frequently updating the app with new react-native versions and uploading it to Google Play.

I suspect that this could be caused by bad behaviour of one of the dependencies. Here is list of my deps, maybe we'll find some overlapping part:

"jsc-android": "^224109.x.x",
"lodash": "^4.17.11",
"moment": "^2.22.2",
"prop-types": "^15.6.2",
"react": "16.5.2",
"react-native": "^0.57.0",
"react-native-animatable": "^1.3.0",
"react-native-billing": "^2.10.0",
"react-native-code-push": "^5.4.2",
"react-native-console-time-polyfill": "^0.0.6",
"react-native-device-info": "^0.22.5",
"react-native-fbsdk": "^0.8.0",
"react-native-firebase": "^4.3.8",
"react-native-htmlview": "^0.13.0",
"react-native-i18n": "^2.0.15",
"react-native-in-app-utils": "^6.0.0",
"react-native-keyboard-aware-scroll-view": "^0.7.2",
"react-native-linear-gradient": "^2.4.2",
"react-native-mixpanel": "1.1.1",
"react-native-modal": "^6.5.0",
"react-native-modal-datetime-picker": "^6.0.0",
"react-native-popup-menu": "^0.14.0",
"react-native-progress": "^3.5.0",
"react-native-sha256": "^1.1.1",
"react-native-snap-carousel": "^3.7.4",
"react-native-sortable-listview": "^0.2.8",
"react-native-splash-screen": "^3.1.1",
"react-native-sqlite-storage": "^3.3.6",
"react-native-uncontrolled-date-picker-ios": "^1.0.0",
"react-native-vector-icons": "^5.0.0",
"react-navigation": "^2.15.0",
"tslib": "^1.9.3",
"uuid": "^3.3.2"
MingFaiYau commented 5 years ago

I also get this problem. Crashlytics show:

Binder.java android.os.BinderProxy.transactNative

Fatal Exception: java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 565108 bytes at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:160) at android.os.Handler.handleCallback(Handler.java:891) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:207) at android.app.ActivityThread.main(ActivityThread.java:7470) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:958)

Caused by android.os.TransactionTooLargeException: data parcel size 565108 bytes at android.os.BinderProxy.transactNative(Binder.java) at android.os.BinderProxy.transact(Binder.java:1147) at android.app.IActivityManager$Stub$Proxy.activityStopped(IActivityManager.java:4005) at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:144) at android.os.Handler.handleCallback(Handler.java:891) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:207) at android.app.ActivityThread.main(ActivityThread.java:7470) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:958)

Here is my dependencies,

    "moment": "^2.23.0",
    "react": "16.6.3",
    "react-native": "^0.57.8",
    "react-native-device-info": "^0.21.5",
    "react-native-firebase": "^5.2.0",
    "react-native-gesture-handler": "^1.0.12",
    "react-native-gifted-chat": "^0.5.0",
    "react-native-i18n": "^2.0.12",
    "react-native-offline": "^3.15.2",
    "react-native-search-box": "0.0.19",
    "react-native-vector-icons": "^6.0.2",
    "react-native-webview": "^2.15.0",
    "react-navigation": "^3.0.9",
    "react-redux": "^5.0.7",
    "redux": "^4.0.0",
    "redux-persist": "^5.10.0",
    "redux-thunk": "^2.2.0"

any idea?

littlehome-eugene commented 5 years ago

@dluksza

Thanks for the input, we updated RN to 0.57.4 and it happens less frequently as you said.

  "@callstack/async-storage": "^1.1.0",
     "@skele/components": "^1.0.0-alpha.29",
     "append-query": "^2.0.1",
     "axios": "^0.17.1",
     "babel-plugin-module-resolver": "^3.1.1",
     "babel-preset-react-native": "^5.0.2",
     "bugsnag-react-native": "^2.10.1",
     "cross-fetch": "^1.1.1",
     "date-arithmetic": "^3.1.0",
     "envinfo": "^5.12.1",
     "haversine": "^1.1.0",
     "isomorphic-fetch": "^2.2.1",
     "jquery": "^2.2.0",
     "jsc-android": "^216113",
     "moment": "^2.17.1",
     "normalizr": "^3.2.4",
     "querystring": "^0.2.0",
     "react": "^16.6.0-alpha.8af6728",
     "react-addons-shallow-compare": "^15.5.2",
     "react-ga": "^2.4.1",
     "react-native": "^0.57.4",
     "react-native-action-button": "^2.8.4",
     "react-native-appsee": "^2.4.15",
     "react-native-autocomplete-input": "^3.5.0",
     "react-native-autoheight-webview": "^0.3.4",
     "react-native-calendars": "^1.19.3",
     "react-native-code-push": "^5.2.2",
     "react-native-code-push-saga": "^1.0.1",
     "react-native-datepicker": "^1.6.0",
     "react-native-device-info": "^0.24.0",
     "react-native-drawer": "^2.5.0",
     "react-native-easy-grid": "^0.1.16",
     "react-native-elements": "^0.18.5",
     "react-native-exit-app": "^1.0.0",
     "react-native-fast-image": "^2.0.1",
     "react-native-fbads": "^4.2.3",
     "react-native-firebase": "^5.1.0",
     "react-native-fit-image": "^1.5.4",
     "react-native-htmlview": "^0.12.1",
     "react-native-image-crop-picker": "^0.20.3",
     "react-native-image-pan-zoom": "^2.1.8",
     "react-native-keyboard-input": "5.2.3",
     "react-native-keyboard-tracking-view": "^5.4.4",
     "react-native-linear-gradient": "^2.4.0",
     "react-native-maps": "^0.21.0",
     "react-native-parallax-scroll-view": "^0.21.3",
     "react-native-permissions": "^1.1.1",
     "react-native-picker": "^4.3.5",
     "react-native-root-toast": "^3.0.0",
     "react-native-safe-area-view": "^0.7.0",
     "react-native-searchbar": "^1.14.0",
     "react-native-snap-carousel": "^3.6.0",
     "react-native-svg": "5.5.1",
     "react-native-swiper": "^1.5.13",
     "react-native-vector-icons": "^6.0.2",
     "react-redux": "^5.0.6",
     "react-router-native": "^4.2.0",
     "react-timer-mixin": "^0.13.3",
     "recompose": "^0.26.0",
     "redux": "^3.7.2",
     "redux-batched-actions": "^0.1.6",
     "redux-persist": "^5.10.0",
     "redux-saga": "^0.16.0",
     "redux-thunk": "^2.2.0",
     "rn-datepicker-nougat-spinner-fix": "^0.2.2",
     "string_score": "git+https://github.com/ThiagoNP/string_score.git",
     "svgs": "^3.0.0",
     "tcomb-form-native": "^0.6.11",
     "url": "^0.11.0",
     "url-join": "^4.0.0",
     "url-loader": "^0.5.7",
     "url-search-params": "^0.10.0",
     "valid-url": "^1.0.9"
byencho commented 5 years ago

The problem is caused by saving too much state in onSaveInstanceState. For details see here. Where is all the saved state coming from? Is it being saved by the views? You can use something like TooLargeTool to debug this. If it's being saved the Activities or Fragments you can use Bridge to get around it. If it's all in the views themselves, that's a bit trickier. (Bridge doesn't currently support saving state for views, but we're looking into it.)

dluksza commented 5 years ago

@byencho, which state are you referring to? Do you mean internal Android view/app state or react state stored in components?

byencho commented 5 years ago

@dluksza I'm not sure what the specific state it is, but the point of entry into the OS (via an onSaveInstanceState method) is either an Activity / Fragment or a View. I'd doubt that the data saved by basic Views internally on their own would cause the problem so I'd think that somewhere the library is manually saving some state in one of these places. I don't know enough about the library itself to say more than that at the moment.

dluksza commented 5 years ago

Unfortunately

$ grep -r onSaveInstanceState node_modules

returns no results. I'm also not saving state manually in android app. Maybe it is done by third party library that is transitive dependency of one of react-native libs...

byencho commented 5 years ago

@dluksza Interesting. OK then I'd recommend taking a look at using TooLargeTool to try and debug what's going on to see if anything being saved jumps out at you as being unusually large. You can see if there are any custom key / value pairs in the bundles or if its only Android OS related. A typical Activity should have a Bundle with the keys android:support:fragment, android:fragments, android:viewHierarchyState. Anything else would point to some custom data being saved somewhere. Or if the android:support:fragment / android:viewHierarchyState values are large you could investigate in the Fragments / Views for more details.

It's certainly possible there is just too much vanilla view state being saved. That would require either (a) a very large number of views that save a decent amount of state (like an EditText) or (b) a small number of views that are saving an abnormally large amount of state based on user input (again like an EditText). I've actually tested this before : if you copy about 14 chapters of Moby Dick into an EditText you can trigger this crash. (That seems to be the type of scenario causing problems here.)

fossage commented 5 years ago

I don't know if this is a red herring or not, but one thing I notice with everyone's dependencies listed is that they are using react-native-firebase. I am also using react-native-firebase and I get this exception as well. The only reason this raises an eyebrow for me is that, according to the TransactionTooLargeException docs:

During a remote procedure call, the arguments and the return value of the call are transferred as Parcel objects stored in the Binder transaction buffer. If the arguments or the return value are too large to fit in the transaction buffer, then the call will fail and TransactionTooLargeException will be thrown.

Doing a global search through my project for uses of Parcel, the only place I see it used is react-native-firebase.

I'm not much of an Android developer, so this may be way off but I would be curious to get other people's thoughts.

BTW, I'm on "react-native-firebase": "^4.3.8",

antishok commented 5 years ago

@fossage FWIW, I got this too but am not using react-native-firebase. But there is a use of Parcel by react-native-camera.

My deps:

  "dependencies": {
    "react": "16.6.3",
    "react-native": "0.58.6",
    "react-native-ble-plx": "^1.0.3",
    "react-native-camera": "^2.0.2",
    "react-native-gesture-handler": "^1.1.0",
    "react-native-sentry": "^0.42.0",
    "react-native-vector-icons": "^6.4.1",
    "react-navigation": "^3.3.2"
  }
byencho commented 5 years ago

@fossage @antishok Have either of you tried using TooLargeTool? That would help track down the culprit pretty quickly I suspect. You could post some results here.

fossage commented 5 years ago

@byencho , unfortunately I have never been able to repro the issue, but I am seeing it logged fairly often in our error tracking service.

byencho commented 5 years ago

@fossage Sure, but even under normal circumstances you might use the tool to see if there is something suspicious going on : too much data saved in the views, data placed in the Bundle from an unsuspecting source, etc. It's very likely that something is saving a small amount of data all the time and under certain conditions that small amount of data passes the limit to trigger a TransactionTooLargeException.

Just as a general example : an Android app might implement a ViewPager with a FragmentStatePagerAdapter. Under normal circumstances, each Fragment will result in a small amount of data getting saved in onSaveInstanceState of the overall Activity. If you happen to have dozens and dozens of them, though, this accumulated data could trigger a TransactionTooLargeException. Something could be happening here with Views.

stale[bot] commented 5 years ago

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

phillbaker commented 5 years ago

We continue to see this bug periodically in production.

It looks like for the Wordpress-Android app (issue linked above), the fix involved using toolargetool.

GlisboaDev commented 5 years ago

Any updates on this issue? We're having many cases in our app, and our bug reports all point to this happening when the user puts the app on the background (Always happens after a sequence of onPause, onSaveInstanceState, onStop). These reports alone is causing the majority of our crashes and the crash rate increased significantly due to it.

shibathethinker commented 5 years ago

We still see this issue as of with React Native 59.9

dkrefta commented 4 years ago

Any clue about that problem? I used android:largeHeap="true" but I'm still facing this issue

idlework commented 4 years ago

I still have this problem with react-native 61.5. Google's Crashalytics show the following:

Caused by android.os.TransactionTooLargeException
data parcel size 402196 bytes
---
android.os.BinderProxy.transactNative (Binder.java)
android.os.BinderProxy.transact (Binder.java:1142)
android.app.IActivityManager$Stub$Proxy.activityStopped (IActivityManager.java:3890)
android.app.servertransaction.PendingTransactionActions$StopInfo.run (PendingTransactionActions.java:144)
android.os.Handler.handleCallback (Handler.java:873)
android.os.Handler.dispatchMessage (Handler.java:99)
android.os.Looper.loop (Looper.java:214)
android.app.ActivityThread.main (ActivityThread.java:6986)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:494)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1445)

My only package that would write data is Firebase, maybe this is the culprit?

stale[bot] commented 4 years ago

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

phillbaker commented 4 years ago

Still an issue!

stale[bot] commented 4 years ago

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

stale[bot] commented 4 years ago

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.

martinsinghk commented 3 years ago

Unfortunately, the issue is still there in RN 0.63.2. Is there anyone managed to fix it?

Muzzamil75 commented 3 years ago

same issue

mit4dev commented 3 years ago

Having the same issue on rn 0.62.2

binlaniua commented 3 years ago

still in rn 0.63.4

nickhealy commented 3 years ago

I am also having this issue (on latest RN), although it is almost certainly due to the app trying to save too much "vanilla" UI, as @byencho mentioned. There is a time when our API sends us an obscene amount of data that we render in a FlatList. @byencho (or anybody else) do you have any recommendations on how to fix this issue? I've pasted my logs from TooLargeTool here. The issue is clearly our viewHierarchyState.

06-22 13:49:46.792 27311 27311 D TooLargeTool: MainActivity.onSaveInstanceState wrote: Bundle214848237 contains 4 keys and measures 450.0 KB when serialized as a Parcel
06-22 13:49:46.792 27311 27311 D TooLargeTool: * com.google.app_measurement.screen_service = 0.2 KB
06-22 13:49:46.792 27311 27311 D TooLargeTool: * android:viewHierarchyState = 449.2 KB
06-22 13:49:46.792 27311 27311 D TooLargeTool: * androidx.lifecycle.BundlableSavedStateRegistry.key = 0.1 KB
06-22 13:49:46.792 27311 27311 D TooLargeTool: * android:fragments = 0.4 KB
leofolive commented 3 years ago

any update?

akshaygpta007 commented 3 years ago

any update?

byencho commented 3 years ago

Because you are not creating and managing the individual views manually, a fix for this would get a little tricky using Bridge. It might be possible though...at a high level, you'd have to do something like this:

This would roughly look something like:

private const val VIEW_HIERARCHY_KEY = "android:viewHierarchyState"

class MainActivity: Activity() {
    @State
    var viewHierarchyState: Bundle? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        // The following code *must* come before the super call
        Bridge.restoreInstanceState(this, savedInstanceState)
        viewHierarchyState?.let { outState.putBundle(VIEW_HIERARCHY_KEY, it) }

        super.onCreate(savedInstanceState)
        ...
    }

    override fun onSaveInstanceState(outState: Bundle) {
        viewHierarchyState = outState.getBundle(VIEW_HIERARCHY_KEY)
        outState.remove(VIEW_HIERARCHY_KEY)
        Bridge.saveInstanceState(this, outState)
    }
}

This all assumes you've already properly set up Bridge (see the repo for details). I haven't tested this out so I can't guarantee it would work but it's at least something to try out.

hsource commented 2 years ago

Also another note: most React Native apps don't heavily depend on the saved instance state for restarting, so I believe (we're testing this right now) it should be safe to just clear the bundle if it's too large. This is what we're trying to add to MainActivity:

    /**
     * Added to not save instance state when the state is too large. When the
     * parcel is too large, a crash occurs in the form of the ones at
     * https://github.com/facebook/react-native/issues/19458
     *
     * This usually happens because the Android activity saves the information
     * for the entire window hierarchy. This can get really large if there are
     * a ton of views in a FlatList:
     * https://android.googlesource.com/platform/frameworks/base/+/808b9f1b730ed7d046c26d0c11181632379ce570/core/java/android/app/Activity.java#2275
     *
     * While this crash actually doesn't affect the functioning of the app, I
     * think it may still affect our Android crash rate stats since it shows
     * up in the Google Play Developer Console. High crash rates lower our
     * Google Play Store ranking.
     *
     * Not saving state should be fine for the user too. We don't rely on
     * instance state for the state of our app, as everything is stored using
     * AsyncStorage inside of JS code instead.
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        try {
            super.onSaveInstanceState(outState);
            Parcel parcel = Parcel.obtain();
            int size;

            parcel.writeBundle(outState);
            size = parcel.dataSize();

            // This was determined by looking at Bugsnag errors like:
            // "java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 529044 bytes"
            //
            // There were no errors for parcels with size < 520000 and many
            // above. As such, we limit the parcel size to 500000 to have a bit
            // of leeway.
            int maximumParcelSize = 500000;
            if (size > maximumParcelSize) {
                outState.clear();
            }

            parcel.recycle();
        } catch (Exception e) {
            // Failed saves don't hurt anyone, so we just swallow the errors
            // Alternatively log a handled error
        }
    }
}
tpisto commented 1 year ago

(we're testing this right now) it should be safe to just clear the bundle if it's too large.

Hi - thank you for the good pointers. Did the fix work for you?

hsource commented 1 year ago

(we're testing this right now) it should be safe to just clear the bundle if it's too large.

Hi - thank you for the good pointers. Did the fix work for you?

This fixed the issue for us without any observable impact. I think the user might lose their saved state of the app, but we have other ways of storing/restoring that.

evelant commented 5 months ago

This still happens in react-native 0.74. I wish issues could get reopened so as not to lose context but that never happens here. That auto-close bot is way too aggressive.