ITADN

Fix crash on commits with many comments and refactor compression in bundle

#1458Pull RequestFs00 创建于 2025-04-13已合并
F
Fs00commented
The main goal of this PR is to fix a crash that occurs when switching away from the commit activity when the commit has many comments (such as https://github.com/git/git/commit/e83c5163316f89bfbde7d9ab23ca2e25604af290 with almost 300 comments), caused by a `TransactionTooLargeException` due to the comments being saved in the fragment args `Bundle` (and then stored in the saved instance state by Android) without compression. However, I've ended up heavily refactoring the code for compressing args in `Bundle`s/`Intent` extras because otherwise I would have introduced more duplication. In summary: - I've made the compression/decompression functions able to work with any kind of object supported by `Parcel`s, so that we don't need to have a different function for each type of object we want to compress - I've removed the compression threshold: objects are now always stored in compressed form when using `IntentUtils.putCompressed*` functions. We were previously setting thresholds to 100/500/800KB assuming that the OS would tolerate serialized payloads up to 1MB, however when debugging I've seen `TransactionTooLargeException` being thrown even for smaller sizes (around 600KB). Indeed, [the docs say](https://developer.android.com/reference/android/os/TransactionTooLargeException.html) (emphasis mine): > The Binder transaction buffer has a limited fixed size, currently 1MB, which is shared by all transactions in progress for the process. Consequently this exception can be thrown when there are many transactions in progress **even when most of the individual transactions are of moderate size**. [And also](https://developer.android.com/guide/components/activities/parcelables-and-bundles#sdbp): > For the specific case of savedInstanceState, the amount of data should be kept small [...]. We recommend that you keep saved state **to less than 50k of data**. So, in the end, I think it's better to play it safer and don't let callers worry about those details. This change also helped a lot in making the code easier to follow and more generic. Furthermore, I've noticed that for compression we could just use a [`DeflaterOutputStream`](https://developer.android.com/reference/java/util/zip/DeflaterOutputStream), a superclass of the `GZipOutputStream` which also lets us tweak the compression level to our needs. I've experimented a bit with the levels and found out that `3` (default is `6` on a 1-9 range) looks like the sweet spot for speed (around 2x faster than `4` and 2,5-3x faster than `6`) without losing much on compressed size (a few tens of KBs at worst for payloads close to 1MB). It might look like a superfluous optimization - and for most scenarios it likely is - but on my Galaxy A3 2017 I've measured the compression of a long wiki article taking 77ms (still acceptable but not quite fast), which was reduced to 29ms simply by tweaking the compression level. Lastly, while I was at it I've renamed the `CommitNoteFragment` and related adapter to `CommitCommentsFragment` (the "notes" part didn't look very obvious to me, maybe a remnant of the past?).
合并状态:已合并 合并于 2025-04-13 关闭于 2025-04-13 0 条评论