{"action":"created","issue":{"url":"https://api.github.com/repos/frakbot/JumpingBeans/issues/2","labels_url":"https://api.github.com/repos/frakbot/JumpingBeans/issues/2/labels{/name}","comments_url":"https://api.github.com/repos/frakbot/JumpingBeans/issues/2/comments","events_url":"https://api.github.com/repos/frakbot/JumpingBeans/issues/2/events","html_url":"https://github.com/frakbot/JumpingBeans/issues/2","id":77296959,"number":2,"title":"Zombie JumpingBeans instance causes java.lang.StackOverflowError","user":{"login":"klaas-loclet","id":9575800,"avatar_url":"https://avatars.githubusercontent.com/u/9575800?v=3","gravatar_id":"","url":"https://api.github.com/users/klaas-loclet","html_url":"https://github.com/klaas-loclet","followers_url":"https://api.github.com/users/klaas-loclet/followers","following_url":"https://api.github.com/users/klaas-loclet/following{/other_user}","gists_url":"https://api.github.com/users/klaas-loclet/gists{/gist_id}","starred_url":"https://api.github.com/users/klaas-loclet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/klaas-loclet/subscriptions","organizations_url":"https://api.github.com/users/klaas-loclet/orgs","repos_url":"https://api.github.com/users/klaas-loclet/repos","events_url":"https://api.github.com/users/klaas-loclet/events{/privacy}","received_events_url":"https://api.github.com/users/klaas-loclet/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/frakbot/JumpingBeans/labels/bug","name":"bug","color":"fc2929"}],"state":"open","locked":false,"assignee":{"login":"rock3r","id":153802,"avatar_url":"https://avatars.githubusercontent.com/u/153802?v=3","gravatar_id":"","url":"https://api.github.com/users/rock3r","html_url":"https://github.com/rock3r","followers_url":"https://api.github.com/users/rock3r/followers","following_url":"https://api.github.com/users/rock3r/following{/other_user}","gists_url":"https://api.github.com/users/rock3r/gists{/gist_id}","starred_url":"https://api.github.com/users/rock3r/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rock3r/subscriptions","organizations_url":"https://api.github.com/users/rock3r/orgs","repos_url":"https://api.github.com/users/rock3r/repos","events_url":"https://api.github.com/users/rock3r/events{/privacy}","received_events_url":"https://api.github.com/users/rock3r/received_events","type":"User","site_admin":false},"milestone":null,"comments":3,"created_at":"2015-05-17T12:15:28Z","updated_at":"2015-05-19T09:20:34Z","closed_at":null,"body":"Hi guys,\r\nI'm using your library for an app project and really like it so far.\r\nHowever, I just stumbled over a rather tricky issue: I'm triggering a JumpingBeans animation on a single TextView from several places in my fragment, like so:\r\n```java\r\nloadingDots = new JumpingBeans.Builder().appendJumpingDots(tvLoading).build();\r\n```\r\nWhen the fragment is paused, I cancel any possibly active animation by calling:\r\n```java\r\nif (loadingDots != null)\r\n        loadingDots.stopJumping();\r\n```\r\nNow, by accident, I actually created a JumpingBeans instance twice, i.e. I assigned a new JumpingBeans instance to `loadingDots` without calling `.stopJumping()` on the old one. This doesn't cause any problem until the users leaves the current activity and transitions to a new one. That's when the zombie JumpingBeans instance (which apparently doesn't get GC'ed) actually takes down the entire app with a `java.lang.StackOverflowError`. The culprit is `JumpingBeansSpan`, which makes an infinitely recursive call to `animation.start()` when the TextView still exists but the span is no longer attached to it: \r\n```java\r\n    @Override\r\n    public void onAnimationUpdate(ValueAnimator animation) {\r\n        // No need for synchronization as this always run on main thread anyway\r\n        TextView v = textView.get();\r\n        if (v != null) {\r\n            if (isAttachedToHierarchy(v)) {\r\n                shift = (int) animation.getAnimatedValue();\r\n                v.invalidate();\r\n            } else {\r\n                // If there is a zombie JumpingBeans instance that is not attached\r\n                // to a view, this code block will cause infinite recursion and a\r\n                // java.lang.StackOverflowError.\r\n                animation.setCurrentPlayTime(0);\r\n                animation.start();\r\n            }\r\n        } else {\r\n                ...\r\n        }\r\n    }\r\n```\r\n*I am aware that this error came from improper use of the library* (now I actually stop and clean up any existent JumpingBeans instance before creating a new one and it works fine). Still, the consequences of this possibly common pitfall seem a bit harsh, so I'd like to suggest the following:\r\n* Detect and prevent recursive starting of the animation in https://github.com/frakbot/JumpingBeans/blob/master/lib/src/main/java/net/frakbot/jumpingbeans/JumpingBeansSpan.java#L85-L86 - this would mitigate the `java.lang.StackOverflowError` and possibly resulting app crashes.\r\n* Even better (if possible): Clear any old JumpingBeans instances that hold a WeakReference to a TextView when a new instance is attached to the same TextView.\r\n\r\nUnfortunately, I don't have time to work out a PR at the moment, but I thought I'd share this issue anyway."},"comment":{"url":"https://api.github.com/repos/frakbot/JumpingBeans/issues/comments/103413104","html_url":"https://github.com/frakbot/JumpingBeans/issues/2#issuecomment-103413104","issue_url":"https://api.github.com/repos/frakbot/JumpingBeans/issues/2","id":103413104,"user":{"login":"rock3r","id":153802,"avatar_url":"https://avatars.githubusercontent.com/u/153802?v=3","gravatar_id":"","url":"https://api.github.com/users/rock3r","html_url":"https://github.com/rock3r","followers_url":"https://api.github.com/users/rock3r/followers","following_url":"https://api.github.com/users/rock3r/following{/other_user}","gists_url":"https://api.github.com/users/rock3r/gists{/gist_id}","starred_url":"https://api.github.com/users/rock3r/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rock3r/subscriptions","organizations_url":"https://api.github.com/users/rock3r/orgs","repos_url":"https://api.github.com/users/rock3r/repos","events_url":"https://api.github.com/users/rock3r/events{/privacy}","received_events_url":"https://api.github.com/users/rock3r/received_events","type":"User","site_admin":false},"created_at":"2015-05-19T09:20:34Z","updated_at":"2015-05-19T09:20:34Z","body":"Hmm that's weird, it should be on `mavenCentral()`. I'll double check. I plan on releasing the new version on `jcenter()`, anyway."}}