-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Fix: Prevent crash when pausing/resuming uploads after screen rotation #6532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix: Prevent crash when pausing/resuming uploads after screen rotation #6532
Conversation
|
✅ Generated APK variants! |
|
Haven't reviewed yet but just thinking if we could get a similar crash in FailedUploadsPresenter due to the same reason 🤔 |
|
Verified the crash in FailedUploadsPresenter (not on this branch). Open question: why can't dagger help instantiate injected properties? PS: this is for me to dig in, just brushing up as it's been a while since I worked on Android :) |
Yes, you are absolutely correct. The |
That's the heart of the issue with configuration changes in Android! Dagger uses the
|
|
I was referring to the presenter variable with |
My mistake for assuming that name; I meant the presenter for the Failed Uploads tab, whatever its name is (since the fragments are handled similarly). Since you verified the crash on the failed uploads side, the approach we used to make the PendingUploadsFragment safe-retrieving the Fragment by tag in the Activity and using safe calls (?.) in the Fragment-will fix that side too. I agree. The core issue is that the Activity can get a hold of the Fragment instance before Dagger's injection process is guaranteed to complete after a rotation. The codebase's standard way of handling configuration changes might be robust for UI/state, but this specific sequence (Rotation -> Fast Menu Click -> External call to a Fragment method) creates a tiny window where the @Inject field is still null. |
|
Would you mind checking how the app handles configuration changes in other activities? |
I’ll be a bit busy until the end of the month as my mid-sem exams are going on. I’ll need some time before I can get back to this issue. |
|
No worries, @Kota-Jagadeesh. All the best for your exams :) |
|
Just wanted to update before you end up resuming your work on this... I raised an issue with a broader scope to standardise how we handle configuration changes: #6538. Please feel free to pick that up if you dig into the nuances to answer my question above but since I brought that up later, you need not handle all the scenarios as part of this PR as long as we're following the best practices even with limited scope 🙌🏻 In case you decide to continue with this one, I'll simplify it: I waited for quite some time before hitting that pause button but still ended up with a crash. So this might not be a timing issue or a race condition. We are possibly not persisting the state at all. I'll narrow down my question as the other one had a much broader scope: could you confirm if making properties nullable is a recommended way while injecting properties like a presenter and share a link to the official docs/stack overflow/blog, if possible? When is this property expected to be null? |
Description (required)
Fixes #6433
What changes did you make and why?
This PR resolves a critical
IllegalStateExceptioncrash that occurred when a user triggered a configuration change (e.g., screen rotation) while on the upload progress screen, and then quickly tapped the "Pause uploads" or "Resume uploads" menu item.The crash was due to a timing mismatch between the Activity, the Fragment lifecycle, and Dagger dependency injection: the host
UploadProgressActivitywas calling methods on thePendingUploadsFragmentbefore the Fragment's dependencies, specifically thependingUploadsPresenter, were re-injected by Dagger after rotation.The following changes implement robust safety mechanisms for tha xternal Fragment interaction:
PendingUploadsFragment.kt:pendingUploadsPresenterto be nullable (@Inject @JvmField var presenter: Presenter? = null). This prevents the initialUninitializedPropertyAccessExceptionand the subsequent customIllegalStateExceptionwe added.pauseUploads(),restartUploads(),deleteUploads()) to use safe calls (presenter?.action()). This ensures the app gracefully aborts the action if the presenter is not yet ready, making the functionality smooth instead of crashy.UploadProgressActivity.kt:pendingUploadsFragment).getPendingUploadsFragment()) that usessupportFragmentManager.findFragmentByTag()right before any fragment method is called. This guarantees the Activity is always interacting with the current, fully attached, and ready Fragment instance, regardless of rotation timing.Tests performed (required)
Tested
ProdDebugonRedmi note 13 5gwith API level35.Steps to verify the fix: