CappielloAntonio / tempo

An open source and lightweight music client for Subsonic, designed and built natively for Android.
GNU General Public License v3.0
1.06k stars 49 forks source link

fix: handle null values for genres, artist ids, and album ids in DownloadHorizontalAdapter #35

Closed timschneeb closed 1 year ago

timschneeb commented 1 year ago

After trying out the new downloads sorting feature (#26), I noticed that when sorting by genre or artists, the app would crash. Apparently, some of my music files that I downloaded from my server are either missing an artist tag or a genre tag which causes a null pointer exception.

This PR switches to the static Objects.equals(x,y) method which can cope with null values properly.

Here's the stacktrace when sorting by 'genre' before applying the fix:

00:16:42.610  E  FATAL EXCEPTION: main
                 Process: com.cappielloantonio.notquitemy.tempo, PID: 24868
                 java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
                    at com.cappielloantonio.tempo.ui.adapter.DownloadHorizontalAdapter.lambda$countSong$12(DownloadHorizontalAdapter.java:147)
                    at com.cappielloantonio.tempo.ui.adapter.DownloadHorizontalAdapter$$ExternalSyntheticLambda17.test(Unknown Source:4)
                    at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:184)
                    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1390)
                    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
                    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:475)
                    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
                    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:236)
                    at java.util.stream.LongPipeline.reduce(LongPipeline.java:455)
                    at java.util.stream.LongPipeline.sum(LongPipeline.java:413)
                    at java.util.stream.ReferencePipeline.count(ReferencePipeline.java:544)
                    at com.cappielloantonio.tempo.ui.adapter.DownloadHorizontalAdapter.countSong(DownloadHorizontalAdapter.java:147)
                    at com.cappielloantonio.tempo.ui.adapter.DownloadHorizontalAdapter.initGenreLayout(DownloadHorizontalAdapter.java:224)
                    at com.cappielloantonio.tempo.ui.adapter.DownloadHorizontalAdapter.onBindViewHolder(DownloadHorizontalAdapter.java:65)
                    at com.cappielloantonio.tempo.ui.adapter.DownloadHorizontalAdapter.onBindViewHolder(DownloadHorizontalAdapter.java:27)
                    at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7747)
                    at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7847)
                    at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6646)
                    at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6917)
                    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6757)
                    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6753)
                    at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2362)
                    at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1662)
                    at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1622)
                    at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:687)
                    at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4645)
                    at androidx.recyclerview.widget.RecyclerView.onMeasure(RecyclerView.java:4022)
                    at android.view.View.measure(View.java:27124)
                    at androidx.constraintlayout.widget.ConstraintLayout$Measurer.measure(ConstraintLayout.java:811)
                    at androidx.constraintlayout.core.widgets.analyzer.BasicMeasure.measure(BasicMeasure.java:466)
                    at androidx.constraintlayout.core.widgets.analyzer.BasicMeasure.measureChildren(BasicMeasure.java:134)
                    at androidx.constraintlayout.core.widgets.analyzer.BasicMeasure.solverMeasure(BasicMeasure.java:278)
                    at androidx.constraintlayout.core.widgets.ConstraintWidgetContainer.measure(ConstraintWidgetContainer.java:120)
                    at androidx.constraintlayout.widget.ConstraintLayout.resolveSystem(ConstraintLayout.java:1594)
                    at androidx.constraintlayout.widget.ConstraintLayout.onMeasure(ConstraintLayout.java:1708)
                    at android.view.View.measure(View.java:27124)
                    at androidx.core.widget.NestedScrollView.measureChildWithMargins(NestedScrollView.java:1695)
                    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
                    at androidx.core.widget.NestedScrollView.onMeasure(NestedScrollView.java:604)
                    at android.view.View.measure(View.java:27124)
                    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
00:16:42.610  E     at androidx.coordinatorlayout.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:795)
                    at com.google.android.material.appbar.HeaderScrollingViewBehavior.onMeasureChild(HeaderScrollingViewBehavior.java:100)
                    at com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior.onMeasureChild(AppBarLayout.java:2376)
                    at androidx.coordinatorlayout.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:866)
                    at android.view.View.measure(View.java:27124)
                    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
                    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
                    at android.view.View.measure(View.java:27124)
                    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
                    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
                    at android.view.View.measure(View.java:27124)
                    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
                    at androidx.coordinatorlayout.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:795)
                    at androidx.coordinatorlayout.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:868)
                    at android.view.View.measure(View.java:27124)
                    at android.widget.LinearLayout.measureVertical(LinearLayout.java:995)
                    at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
                    at android.view.View.measure(View.java:27124)
                    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
                    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
                    at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:145)
                    at android.view.View.measure(View.java:27124)
                    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
                    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
                    at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
                    at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
                    at android.view.View.measure(View.java:27124)
                    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
                    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
                    at android.view.View.measure(View.java:27124)
                    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
                    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
                    at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
                    at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
                    at android.view.View.measure(View.java:27124)
                    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
                    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
                    at com.android.internal.policy.DecorView.onMeasure(DecorView.java:1237)
                    at android.view.View.measure(View.java:27124)
                    at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:4430)
                    at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:3135)
                    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3427)
                    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2831)
                    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:10311)
                    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1063)
                    at android.view.Choreographer.doCallbacks(Choreographer.java:845)
                    at android.view.Choreographer.doFrame(Choreographer.java:780)
                    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1048)
                    at android.os.Handler.handleCallback(Handler.java:938)
                    at android.os.Handler.dispatchMessage(Handler.java:99)
                    at android.os.Looper.loopOnce(Looper.java:226)
                    at android.os.Looper.loop(Looper.java:313)
                    at android.app.ActivityThread.main(ActivityThread.java:8641)
                    at java.lang.reflect.Method.invoke(Native Method)
                    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1133)
CappielloAntonio commented 1 year ago

Thank you so much for your PR!