0

In a chatting window I have a feature like self destructing message after a duration. For which I have a class which shows burning animation after the duration. While sending text the handler and timer I used in the below class is working fine for 2-3 times then some animation discrepancy is found like the fire isn't starting in exact location.

Apart from that while sending a file from file chooser fragment when it returns to the recyclerview of the chatwindow nothing happens until I touch the screen and scroll it a bit. While debugging I noticed that the first time when bindview is called after sending a file the handler and timer is not executing properly. Instead if I navigate back and enter the chatwindow again it's working perfectly. It burns the filemessage perfectly then.

The burner class:

public class Burner {
private static final TaggedLogger logger = new TaggedLogger("Burner");

public static void burnMessage(final TextMessageViewHolder holder, final BurnerListener listener) {
    final int DURATION = 3000;
    if (!holder.isBurning) {
        final Handler handler = new Handler(Looper.getMainLooper());
        final Animator.AnimatorListener animatorListener = new Animator.AnimatorListener() {

            @Override
            public void onAnimationStart(Animator animator) {
                logger.log("onAnimationStart");

            }

            @Override
            public void onAnimationEnd(Animator animator) {
                listener.onBurnFinished();
            }

            @Override
            public void onAnimationCancel(Animator animator) {

            }

            @Override
            public void onAnimationRepeat(Animator animator) {

            }
        };
        holder.isBurning = true;
        holder.fireAnimationHolder.setVisibility(View.VISIBLE);
        holder.fireAnimationHolder.measure(0, 0);
        Activity activity = (Activity) ChatProperties.getChatWindowContext();

        if (activity != null) {
            final ParticleSystem particleSystem = new ParticleSystem(activity, 48, R.drawable.fire_2, DURATION)
                    .setSpeedByComponentsRange(-0.025f, 0.0f, -0.06f, -0.08f)
                    .setAcceleration(0.00003f, 0)
                    .setInitialRotationRange(30, 45)
                    .addModifier(new AlphaModifier(255, 0, 200, 1000))
                    .addModifier(new ScaleModifier(0.5f, 2f, 0, 1000));
            holder.fireAnimationHolder.post(new Runnable() {
                @Override
                public void run() {
                    holder.fireAnimationHolder.measure(0,0);
                    int fireAnimationHolderWidth = holder.fireAnimationHolder.getWidth();
//                    logger.log("fireAnimationHolderWidth = " + fireAnimationHolderWidth);
                    particleSystem.emit(holder.fireSource, 12);
                    holder.fireSource.animate().translationXBy(fireAnimationHolderWidth).setStartDelay(500).setDuration(DURATION).setListener(animatorListener).start();
                    holder.fireSourceController.setPivotX(0);
                    holder.fireSourceController.animate().alpha(1f).scaleX(1f).setDuration(DURATION).start();
                }
            });
            new Timer().scheduleAtFixedRate(new TimerTask() {
                int elapsedTime = 0;

                @Override
                public void run() {
                    elapsedTime += 300;
                    if (elapsedTime >= DURATION) {
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                particleSystem.cancel();
                            }
                        });

                        this.cancel();
                    } else {
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                particleSystem.updateEmitPoint(holder.fireSource, Gravity.CENTER);
                            }
                        });
                    }
                }
            }, 100, 300);
        }
    }
}

This burnMessage method is called from the bindview of the TextMessageViewholder's bindview method and FilemessageViewHolder extends TextMessageViewHoler class.

In TextMessageViewHolder's bindview method this function is called if it's a self destructing message:

private void handleMessageBurning(final Message message) {
    if (message.imBurnTime > 0 && BurnMessageHelper.animatedBurnMessageEntryMap.containsKey(message.callerId)) {
        Log.e("BurnThread","message to be burned");
        Burner.burnMessage(this, new BurnerListener() {
            @Override
            public void onBurnFinished() {
                if (ChatProperties.isGroupChat) {
                    DataHelper.getInstance().deleteGroupMessage(Target.target, message.callerId);
                } else {
                    DataHelper.getInstance().deleteMessage(Target.target, message.callerId);
                }
                BurnMessageHelper.animatedBurnMessageEntryMap.remove(message.callerId);
                isBurning = false;
            }
        });
    } else {
        fireAnimationHolder.setVisibility(View.GONE);
    }
}

What is happening here? Does the thread of the timer can't run in main thread here due to some reason? Please help. Thanks.

N.B. I tried this in Marshmallow, Nougat and Oreo.

Zim
  • 182
  • 1
  • 1
  • 10
  • and what do you need `Timer` for? cannot you use a `Handler` and one of `send*Message[Delayed|AtTime]` method instead? – pskink May 07 '18 at 06:56
  • Timer is for the animation to shift the burn effect from right to left of the message... – Zim May 07 '18 at 07:13
  • if you have threading issues cannot you use a `Handler` and one of `send*Message[Delayed|AtTime]` method instead? – pskink May 07 '18 at 07:18
  • I think you might misunderstand the self destructing message. After selecting the duration the message is sent. You can see the message in the chat window. After the duration has been elapsed the message will be deleted showing a burn animation effect. – Zim May 07 '18 at 07:27
  • did you check `android.os.Handler` javadocs and `send*()` methods? if so, whats unclear? – pskink May 07 '18 at 07:29
  • okay I am checking now... – Zim May 07 '18 at 07:38

0 Answers0