-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Fix transaction too large in channel tab fragments #10673
Fix transaction too large in channel tab fragments #10673
Conversation
Quality Gate passedThe SonarCloud Quality Gate passed, but some issues were introduced. 1 New issue |
tabHandler = result.getService() | ||
.getChannelTabLHFactory() | ||
.fromQuery(tabHandler.getId(), tabHandler.getContentFilters(), | ||
tabHandler.getSortFilter()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This causes a crash. Use media.ccc.de service, open a channel / conference. getChannelTabLHFactory()
is null
for that service:
Exception
- User Action: ui error
- Request: ACRA report
- Content Country: DE
- Content Language: de-
- App Language: en
- Service: none
- Version: 0.26.0
- OS: Linux Android 12 - 32
Crash log
java.lang.NullPointerException: Attempt to invoke virtual method 'org.schabi.newpipe.extractor.linkhandler.ListLinkHandler org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory.fromQuery(java.lang.String, java.util.List, java.lang.String)' on a null object reference
at org.schabi.newpipe.fragments.list.channel.ChannelTabFragment.handleResult(ChannelTabFragment.java:133)
at org.schabi.newpipe.fragments.list.channel.ChannelTabFragment.handleResult(ChannelTabFragment.java:37)
at org.schabi.newpipe.fragments.list.BaseListInfoFragment.lambda$startLoading$0(BaseListInfoFragment.java:150)
at org.schabi.newpipe.fragments.list.BaseListInfoFragment.$r8$lambda$yX6S2nKGSbR70YowNdSpGemC7q4(BaseListInfoFragment.java:0)
at org.schabi.newpipe.fragments.list.BaseListInfoFragment$$ExternalSyntheticLambda4.accept(R8$$SyntheticClass:0)
at io.reactivex.rxjava3.internal.observers.ConsumerSingleObserver.onSuccess(ConsumerSingleObserver.java:62)
at io.reactivex.rxjava3.internal.operators.single.SingleObserveOn$ObserveOnSingleObserver.run(SingleObserveOn.java:81)
at io.reactivex.rxjava3.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:123)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7870)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
What is it?
Description of the changes in your PR
This PR contains a really hacky workaround, that avoids storing useless data in the
ChannelTabFragment
state.ChannelTabFragment
uses the corresponding tab link handler to be able to fetch data, since unlike other things in the extractor, channel tabs are not supposed to be obtained from a url (e.g. provided by the user), but rather always from a channel page internally in the app.The problem is,
ReadyChannelTabListLinkHandler
might contain raw JSON data that uses a lot of memory (e.g. ~800KB for YouTube). While 800KB doesn't seem much, if you combine just a couple of channel tab fragments you easily go over the 1MB save&restore transaction limit, and getTransactionTooLargeException
s.What this PR does is to discard the
ReadyChannelTabListLinkHandler
after the first time the raw data has been parsed (i.e. the fragment'shandleResult
has been called). A new link handler with the same properties is then created. The good thing is, even if now the raw data is not in the link handler anymore, ifgetChannelTab
is called on the newly created link handler, the app cache will kick in to still prevent network requests. Note that I didn't test this link-handler-recreation with all services, I will let users do this (or @AudricV could provide some feedback).A proper solution would require rethinking about
ReadyChannelTabListLinkHandler
s, but that's out of scope for 0.26.0. We might need to rethink how the cache works, and instead of returning link handlers with raw data (which turned out to be a really bad idea) , we should put the raw data directly in an extractor cache.You can test the changes by putting one channel from all NewPipe services (Youtube, Soundcloud, ...) as a main page tab. Then open settings and the app should not crash. All video/audio tabs from all channels should still allow e.g. playing in the background without crashing.
Fixes the following issue(s)
APK testing
The APK can be found by going to the "Checks" tab below the title. On the left pane, click on "CI", scroll down to "artifacts" and click "app" to download the zip file which contains the debug APK of this PR. You can find more info and a video demonstration on this wiki page.
Due diligence