Apps-android-commons: Dialog not showing up.

Created on 23 Jun 2019  路  5Comments  路  Source: commons-app/apps-android-commons

Summary:

Dialogs are not showing up(sometimes) in the HomePage, because the parser says that the current dialog view already has a parent and adding it to another parent would require us to remove this dialog view from the existing parent.

System logs:

```
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:5034)
at android.view.ViewGroup.addView(ViewGroup.java:4865)
at android.view.ViewGroup.addView(ViewGroup.java:4837)
at com.android.internal.app.AlertController.setupCustomContent(AlertController.java:627)
at com.android.internal.app.AlertController.setupView(AlertController.java:521)
at com.android.internal.app.AlertController.installContent(AlertController.java:264)
at android.app.AlertDialog.onCreate(AlertDialog.java:436)
at android.app.Dialog.dispatchOnCreate(Dialog.java:407)
at android.app.Dialog.show(Dialog.java:302)
at fr.free.nrw.commons.utils.DialogUtil.showSafely(DialogUtil.java:33)
at fr.free.nrw.commons.utils.DialogUtil.showAlertDialog(DialogUtil.java:140)
at fr.free.nrw.commons.utils.DialogUtil.showAlertDialog(DialogUtil.java:96)
at fr.free.nrw.commons.contributions.ContributionsFragment.showNearbyCardPermissionRationale(ContributionsFragment.java:523)
at fr.free.nrw.commons.contributions.ContributionsFragment.checkPermissionsAndShowNearbyCardView(ContributionsFragment.java:504)
at fr.free.nrw.commons.contributions.ContributionsFragment.onResume(ContributionsFragment.java:484)
at androidx.fragment.app.Fragment.performResume(Fragment.java:2499)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:926)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1229)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1295)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2605)
at androidx.fragment.app.FragmentManagerImpl.dispatchResume(FragmentManagerImpl.java:2577)
at androidx.fragment.app.FragmentController.dispatchResume(FragmentController.java:267)
at androidx.fragment.app.FragmentActivity.onResumeFragments(FragmentActivity.java:463)
at androidx.fragment.app.FragmentActivity.onPostResume(FragmentActivity.java:453)
at androidx.appcompat.app.AppCompatActivity.onPostResume(AppCompatActivity.java:173)
at android.app.Activity.performResume(Activity.java:7325)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3814)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3854)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6718)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
2019-06-23 10:36:28.746 10262-10262/fr.free.nrw.commons.beta E/ContributionsFragment: onFragmentResumed fr.free.nrw.commons.contributions.ContributionsListFragment

Device and Android version:

Google Pixel, Api 27

Commons app version:

2.10.2-debug

Most helpful comment

I'm going to take a look at this and see what I can find or fix

All 5 comments

I'm going to take a look at this and see what I can find or fix

Thanks for taking this up @albendz :-)

To repro, just dismiss and reopen the app (don't end the app process).

My stack:

2019-07-16 18:53:50.754 7112-7112/fr.free.nrw.commons.beta E/DialogUtil: Could not show dialog. java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. at android.view.ViewGroup.addViewInner(ViewGroup.java:4915) at android.view.ViewGroup.addView(ViewGroup.java:4746) at android.view.ViewGroup.addView(ViewGroup.java:4718) at com.android.internal.app.AlertController.setupCustomContent(AlertController.java:606) at com.android.internal.app.AlertController.setupView(AlertController.java:500) at com.android.internal.app.AlertController.installContent(AlertController.java:258) at android.app.AlertDialog.onCreate(AlertDialog.java:425) at android.app.Dialog.dispatchOnCreate(Dialog.java:403) at android.app.Dialog.show(Dialog.java:302) at fr.free.nrw.commons.utils.DialogUtil.showSafely(DialogUtil.java:33) at fr.free.nrw.commons.utils.DialogUtil.showAlertDialog(DialogUtil.java:140) at fr.free.nrw.commons.utils.DialogUtil.showAlertDialog(DialogUtil.java:96) at fr.free.nrw.commons.contributions.ContributionsFragment.showNearbyCardPermissionRationale(ContributionsFragment.java:444) at fr.free.nrw.commons.contributions.ContributionsFragment.checkPermissionsAndShowNearbyCardView(ContributionsFragment.java:425) at fr.free.nrw.commons.contributions.ContributionsFragment.onResume(ContributionsFragment.java:405) at androidx.fragment.app.Fragment.performResume(Fragment.java:2499) at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:926) at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1229) at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1295) at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2605) at androidx.fragment.app.FragmentManagerImpl.dispatchResume(FragmentManagerImpl.java:2577) at androidx.fragment.app.FragmentController.dispatchResume(FragmentController.java:267) at androidx.fragment.app.FragmentActivity.onResumeFragments(FragmentActivity.java:463) at androidx.fragment.app.FragmentActivity.onPostResume(FragmentActivity.java:453) at androidx.appcompat.app.AppCompatActivity.onPostResume(AppCompatActivity.java:173) at android.app.Activity.performResume(Activity.java:7103) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3620) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3685) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1643) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6541) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

The view that is throwing the exception is the customView being sent to the DialogUtils.showAlertDialog. This happens for onResume because Dialog1 (the dialog created before suspend) has the customView and a new dialog Dialog2 (the dialog created after suspend) uses the same customView (who already has Dialog1 as a parent).

A few options I'm considering:

  • Dismiss alert dialogs on suspend because it is being recreated on resume
  • Figure out if a dialog has already been created and don't create another on resume
  • On resume, if the customView already has a parent, deconstruct it or dismiss it and create the new one

The primary example I'm looking at is the location permissions dialog.

Dismiss alert dialogs on suspend because it is being recreated on resume
Figure out if a dialog has already been created and don't create another on resume

These two will require considerable changes, the DialogUtils is used from many places. The third option would solve the issue for now and IMO we can create another issue to refactor the DialogUtils to make sure multiple instances are not created.

Was this page helpful?
0 / 5 - 0 ratings