Summary:
The application is crashing.
If one clicks on an uploaded picture from the home screen then tries to change the theme of the application(dark/light) then returning to the previous activity the application will crash.
Steps to reproduce:
System logs:
Add logcat files here (if possible).
2020-01-28 06:25:37.837 20244-20244/fr.free.nrw.commons.beta E/AndroidRuntime: FATAL EXCEPTION: main
Process: fr.free.nrw.commons.beta, PID: 20244
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ProgressBar.setVisibility(int)' on a null object reference
at fr.free.nrw.commons.contributions.ContributionsListFragment.showProgress(ContributionsListFragment.java:174)
at fr.free.nrw.commons.contributions.ContributionsFragment.showProgress(ContributionsFragment.java:567)
at fr.free.nrw.commons.contributions.ContributionsPresenter.onLoadFinished(ContributionsPresenter.java:76)
at fr.free.nrw.commons.contributions.ContributionsPresenter.onLoadFinished(ContributionsPresenter.java:26)
at androidx.loader.app.LoaderManagerImpl$LoaderObserver.onChanged(LoaderManagerImpl.java:250)
at androidx.lifecycle.LiveData.considerNotify(LiveData.java:113)
at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:131)
at androidx.lifecycle.LiveData.setValue(LiveData.java:289)
at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:33)
at androidx.loader.app.LoaderManagerImpl$LoaderInfo.setValue(LoaderManagerImpl.java:189)
at androidx.loader.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManagerImpl.java:174)
at androidx.loader.content.Loader.deliverResult(Loader.java:132)
at androidx.loader.content.CursorLoader.deliverResult(CursorLoader.java:109)
at androidx.loader.content.CursorLoader.onStartLoading(CursorLoader.java:155)
at androidx.loader.content.Loader.startLoading(Loader.java:285)
at androidx.loader.app.LoaderManagerImpl$LoaderInfo.onActive(LoaderManagerImpl.java:77)
at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:418)
at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:376)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:355)
at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:293)
at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:333)
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:138)
at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:124)
at androidx.lifecycle.ReportFragment.dispatch(ReportFragment.java:122)
at androidx.lifecycle.ReportFragment.onStart(ReportFragment.java:82)
at android.app.Fragment.performStart(Fragment.java:2548)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1334)
at android.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1581)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1642)
at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManager.java:3051)
at android.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:3008)
at android.app.FragmentController.dispatchStart(FragmentController.java:193)
at android.app.Activity.performStart(Activity.java:7264)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2970)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ClientTransactionHandler.executeTransaction(ClientTransactionHandler.java:55)
at android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:4806)
at android.app.ActivityThread.access$3300(ActivityThread.java:200)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1841)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6823)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
2020-01-28 06:25:37.837 20244-20244/fr.free.nrw.commons.beta E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
2020-01-28 06:25:37.845 20244-20244/fr.free.nrw.commons.beta E/ACRA: ACRA caught a NullPointerException for fr.free.nrw.commons.beta
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ProgressBar.setVisibility(int)' on a null object reference
at fr.free.nrw.commons.contributions.ContributionsListFragment.showProgress(ContributionsListFragment.java:174)
at fr.free.nrw.commons.contributions.ContributionsFragment.showProgress(ContributionsFragment.java:567)
at fr.free.nrw.commons.contributions.ContributionsPresenter.onLoadFinished(ContributionsPresenter.java:76)
at fr.free.nrw.commons.contributions.ContributionsPresenter.onLoadFinished(ContributionsPresenter.java:26)
at androidx.loader.app.LoaderManagerImpl$LoaderObserver.onChanged(LoaderManagerImpl.java:250)
at androidx.lifecycle.LiveData.considerNotify(LiveData.java:113)
at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:131)
at androidx.lifecycle.LiveData.setValue(LiveData.java:289)
at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:33)
at androidx.loader.app.LoaderManagerImpl$LoaderInfo.setValue(LoaderManagerImpl.java:189)
at androidx.loader.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManagerImpl.java:174)
at androidx.loader.content.Loader.deliverResult(Loader.java:132)
at androidx.loader.content.CursorLoader.deliverResult(CursorLoader.java:109)
at androidx.loader.content.CursorLoader.onStartLoading(CursorLoader.java:155)
at androidx.loader.content.Loader.startLoading(Loader.java:285)
at androidx.loader.app.LoaderManagerImpl$LoaderInfo.onActive(LoaderManagerImpl.java:77)
at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:418)
at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:376)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:355)
at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:293)
at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:333)
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:138)
at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:124)
at androidx.lifecycle.ReportFragment.dispatch(ReportFragment.java:122)
at androidx.lifecycle.ReportFragment.onStart(ReportFragment.java:82)
at android.app.Fragment.performStart(Fragment.java:2548)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1334)
at android.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1581)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1642)
at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManager.java:3051)
at android.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:3008)
at android.app.FragmentController.dispatchStart(FragmentController.java:193)
at android.app.Activity.performStart(Activity.java:7264)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2970)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ClientTransactionHandler.executeTransaction(ClientTransactionHandler.java:55)
at android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:4806)
at android.app.ActivityThread.access$3300(ActivityThread.java:200)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1841)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6823)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
2020-01-28 06:25:37.846 20244-20244/fr.free.nrw.commons.beta E/ACRA: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
Device and Android version:
Device Model: Redmi Note 7 Pro
Version: Android 9
Is it the stock version from the manufacturer or a custom ROM ? Yes
Commons app version:
version: 2.12.2-debug
branch: master
Screen-shots:

Would you like to work on the issue?
Yes. I would like to work on the issue.
I would like to work on this @nicolas-raoul @maskaravivek
@animeshk08 It is yours, feel free to post updates on this thread :)
After looking a lot through the source code. I understand that the problem persists because we try to access a view element before the view is actually created. This happens in ContributionsFragment.
When the activity is recreated as there are savedinstances the following segment is executed.
Line:145
if (savedInstanceState != null) {
mediaDetailPagerFragment = (MediaDetailPagerFragment) getChildFragmentManager()
.findFragmentByTag(MEDIA_DETAIL_PAGER_FRAGMENT_TAG);
contributionsListFragment = (ContributionsListFragment) getChildFragmentManager()
.findFragmentByTag(CONTRIBUTION_LIST_FRAGMENT_TAG);
shouldShowMediaDetailsFragment = savedInstanceState.getBoolean("mediaDetailsVisible");
}
However both mediaDetailPagerFragment and contributionsListFragment have not created their views yet. Hence the app crashes at Line:567
contributionsListFragment.showProgress(shouldShow);
as it could not find the view of progressbar
One possible solution I found was to finish and start the activity again instead of recreating. However, in this case, the state of the application is not maintained. So I don't know we would actually want that.
One more thing I don't understand the ability to open a nav drawer when you open an image to view because the left-most button indicates the functionality that we can go back at this stage. Maybe another solution would be to not show the navdrawer at all.
.
Can anyone help me with a better approach? @ashishkumar0207
Also, while exploring the bug I found that it was very prominent as it replicates itself even in the Bookmark section and Explore section.
@animeshk08 Another simple (possible) solution should be to change the lifecycle callbacks where the presenter is attached/detached, instead of doing those in onCreateView & onDestroyView, we could do that in onResume & onStop (or if you think another better place). Ideally, the showProgress should not be called after the fragment is not longer active
Can I work on this issue?
@animeshk08 How is your progress? :-)
I want to work on this,
Assign me.
@4D17Y4 I think you already have another issue assigned? :-)
Since Animeshk08 has not replied, @gouri-panda can have this one if not already working on any other issue.