Skip to content
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

App crash when calling showAlignBottom #192

Closed
PiyushSinha-tb opened this issue May 26, 2021 · 11 comments
Closed

App crash when calling showAlignBottom #192

PiyushSinha-tb opened this issue May 26, 2021 · 11 comments
Labels
Released Released already on the latest version.

Comments

@PiyushSinha-tb
Copy link

PiyushSinha-tb commented May 26, 2021

  • Affected Device(s) [Android 11,10,9,8]

Fatal Exception: java.lang.NullPointerException
Attempt to read from field 'int android.view.ViewGroup$LayoutParams.width' on a null object reference

com.skydoves.balloon.Balloon$showAlignBottom$$inlined$show$1.run
Same code working great with showAlignTop

If you want I can share Firebase Crashlytics logs.

Piyush Sinha
Testbook.com

@skydoves
Copy link
Owner

Hi could you share your crashlytics log and the library version?
And it will be help to share the balloon related codes. Thanks!

@PiyushSinha-tb
Copy link
Author

Firebase Crashlytics Text:
Fatal Exception: java.lang.NullPointerException: Attempt to read from field 'int android.view.ViewGroup$LayoutParams.width' on a null object reference
at android.widget.PopupWindow.alignToAnchor(PopupWindow.java:2504)
at android.widget.PopupWindow.access$000(PopupWindow.java:107)
at android.widget.PopupWindow$1.onViewAttachedToWindow(PopupWindow.java:241)
at android.view.View.dispatchAttachedToWindow(View.java:19865)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3515)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3515)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3515)
at android.view.ViewGroup.addViewInner(ViewGroup.java:5317)
at android.view.ViewGroup.addView(ViewGroup.java:5089)
at android.view.ViewGroup.addView(ViewGroup.java:5029)
at androidx.recyclerview.widget.RecyclerView$5.addView(RecyclerView.java:889)
at androidx.recyclerview.widget.ChildHelper.addView(ChildHelper.java:107)
at androidx.recyclerview.widget.RecyclerView$LayoutManager.addViewInt(RecyclerView.java:8902)
at androidx.recyclerview.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:8860)
at androidx.recyclerview.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:8848)
at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1645)
at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1591)
at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:668)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4309)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:4012)
at androidx.recyclerview.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1998)
at androidx.recyclerview.widget.RecyclerView.scrollByInternal(RecyclerView.java:2067)
at androidx.recyclerview.widget.RecyclerView.scrollBy(RecyclerView.java:1880)
at androidx.recyclerview.widget.RecyclerView$LayoutManager.requestChildRectangleOnScreen(RecyclerView.java:10207)
at androidx.recyclerview.widget.RecyclerView$LayoutManager.requestChildRectangleOnScreen(RecyclerView.java:10179)
at androidx.recyclerview.widget.RecyclerView.requestChildRectangleOnScreen(RecyclerView.java:3072)
at android.view.View.requestRectangleOnScreen(View.java:7707)
at android.widget.PopupWindow.findDropDownPosition(PopupWindow.java:1795)
at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:1419)
at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:1380)
at com.skydoves.balloon.Balloon$showAlignBottom$$inlined$show$1.run(Balloon.java:2092)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:227)
at android.app.ActivityThread.main(ActivityThread.java:7822)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1026)

Skydoves Version :1.3.1

Skydoves Related Code In My app
balloon =
new Balloon.Builder(requireContext())
.setLayout(R.layout.item_pyp_onboarding_screen)
.setArrowSize(12)
.setDismissWhenTouchOutside(false)
.setPreferenceName("showOnboarding")
.setShowCounts(1)
.setBackgroundDrawableResource(R.drawable.pyp_onboarding_gradient_card)
.setArrowOrientation(ArrowOrientation.BOTTOM)
.setArrowOrientationRules(ArrowOrientationRules.ALIGN_ANCHOR)
.setArrowPositionRules(ArrowPositionRules.ALIGN_ANCHOR)
.setMarginLeft(15)
.setMarginRight(15)
.setArrowColorResource(R.color.blue_1242cf)
.setWidth(BalloonSizeSpec.WRAP)
.setHeight(BalloonSizeSpec.WRAP)
.setBalloonAnimation(BalloonAnimation.OVERSHOOT)
.setIsVisibleOverlay(true)
.setOverlayColorResource(R.color.overlay)
.setOverlayShape(new BalloonOverlayCircle(70f))
.setAlpha(1f) // sets the visibility of the overlay for highlighting an//
// anchor.
.setBalloonOverlayAnimation(
BalloonOverlayAnimation.FADE) // default is fade.
.setDismissWhenOverlayClicked(
false) // disable dismissing the balloon when the overlay is//
// clicked.
.build();

    ImageView button = balloon.getContentView().findViewById(R.id.closeIcon_IV);
    button.setOnClickListener(
            v -> {
                balloon.dismiss();
                dashboardViewModel.setShowStudyToolTip(true);
            });

After Initializing it in Fragment I passed the reference to Recylerview Adapter something like this
dashboardAdapter =
new DashboardRecyclerAdapter(
....,
balloon,
isAppBannerAdded);
And then i call show align top /align bottom in Adapter
if (isOldUser && isBannerVisisble && MySharedPreferences.showPypOnboarding()) {
try {
ballon.showAlignTop(pypIv);
} catch (Exception ignored) {
}
newBadgeTV.setVisibility(View.GONE);
} else if (isOldUser && !isBannerVisisble && MySharedPreferences.showPypOnboarding()) {
try {
ballon.showAlignBottom(pypIv);
} catch (Exception ignored) {
}
newBadgeTV.setVisibility(View.GONE);
} else {
if (!isOldUser) {
MySharedPreferences.setOnboardingScreen(false);
dashboardViewModel.setShowStudyToolTip(false);
}
if (shouldShownNewTag()) {
newBadgeTV.setVisibility(View.VISIBLE);
} else {
newBadgeTV.setVisibility(View.GONE);
}
}
is Banner is the deciding factor that I have to call alignBottom or alignTop

@skydoves
Copy link
Owner

skydoves commented May 26, 2021

I guess from your reporting, the user tried to show the balloon when the fragment or view already has been detached from the Window (Activity). It seems to need a check before showing or dismissing.

if (fragment.isAdded) {
 // show or dismiss
}

@PiyushSinha-tb
Copy link
Author

Thanks bro.I will try it and let you know it works or not

@znakeeye
Copy link

znakeeye commented May 29, 2021

Interesting. I actually removed this very check December last year. Thought it was no longer needed.

PS. I also checked for resumed state. Not sure why though :)

if (!fragment.isAdded() || !fragment.isResumed()) {
    // Do NOT show
}

Looking through my code, I see that I did add some lifecycle handling. Maybe this is a possible solution to this problem?

.setLifecycleOwner(fragment)

@skydoves
Copy link
Owner

@znakeeye
Hi, the setLifecycleOwner function only does dismiss the balloon based on lifecycles for preventing memory leaks.
So showing the balloon is another problem. I will check later whether can prevent showing the balloon if the fragment's lifecycle is already detached from the Activity. 🤔

@renard314
Copy link

I'm seeing a similar crash when showing a Balloon. The reason in my case is that private inline fun show is checking the lifecycle but then is doing a View#post to actually show the window which means that in time when the post runnable gets executed the activity could be destroyed already

Fatal Exception: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
       at android.view.ViewRootImpl.setView(ViewRootImpl.java:981)
       at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:387)
       at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:96)
       at android.widget.PopupWindow.originalInvokePopup(PopupWindow.java:1590)
       at android.widget.PopupWindow.invokePopup(PopupWindow.java:1575)
       at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:1426)
       at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:1382)
       at com.skydoves.balloon.Balloon$showAlignBottom$$inlined$show$1.run(Balloon.java:1449)
       at android.os.Handler.handleCallback(Handler.java:883)
       at android.os.Handler.dispatchMessage(Handler.java:100)
       at android.os.Looper.loop(Looper.java:226)
       at android.app.ActivityThread.main(ActivityThread.java:7592)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

@skydoves
Copy link
Owner

@renard314
Sorry for the late reply.
I just released a snapshot 1.3.4-SNAPSHOT on the maven repository.
Could you check the crash still happen on the new version? Thanks!

@znakeeye
Copy link

Took a quick glance at the changes. I believe your fix reduces the likelihood of this crash. It doesn't fix it 100%. Those conditions must be checked at the time the runnable gets executed. No?

@skydoves
Copy link
Owner

It seems a concurrency & timing issue. If you find any improvements by using the SNAPSHOT, please let me know. 😄

@skydoves
Copy link
Owner

skydoves commented Jul 2, 2021

These changes included in the new stable 1.3.5!

@skydoves skydoves added the Released Released already on the latest version. label Jul 2, 2021
@skydoves skydoves closed this as completed Jul 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Released Released already on the latest version.
Projects
None yet
Development

No branches or pull requests

4 participants