0

I have an activity that gets started by a background service in order to show scrolling message(s) that the service receives from a server. It's possible to have just one scrolling message or a set of multiple to scroll, one at a time.

My question is what is the ideal way to manage cycling the scrolling of multiple messages, and multiple sets of multiple messages? I've tried my cycler loop within worker threads, AsyncTask, etc.

The Details:

My scroll activity receives the message(s) to show, as an array of strings available for it to access from the service's scope. Say, for example, the service starts the activity in order to scroll several messages, one after another:

  1. My service populates MyService.messages[] with the messages to show and then starts MyScrollActivity.
  2. MyScrollActivity gets size of MyService.messages[]. If >1, start MyCyclerThread (or AsyncTask, etc. - haven't figured out best way!)
  3. MyCyclerThread loops through MyService.messages[] and sets MyScrollActivity TextView with messages[i] and animates across screen once, one message-iteration at a time (one message scrolls across, then the next, etc. - at end of loop, it starts over at i=0 and repeats the messages again.
  4. Step 3 repeats until activity is taken down by the service or another activity is shown. The cycler-thread (or whatever - the loop) needs to die at this time.

I want that particular worker thread (that's doing the looping) to die and never come back whenever its activity stops. But for some reason, whenever the activity is restarted (say a new batch of messages comes in to display), the old cycler/worker thread resurrects, along with a new one for the new messages.

I've tried adding Thread.currentThread().interrupt() to the activity's onPause and onDestroy methods, and I see in my logging that the thread does get interrupted. But like I said, it resurrects (even with the same ID it had before) and starts its loop again. This means for however many 'X' times I start my activity, I also get 'X-1' number of threads running.

I toyed with Activity single-instance XML, various "isThreadABCrunning" flags, etc. I've even tried using an AsyncTask for my cycler loop. I'm running out of ideas.

Help, I'm beginner/intermediate in Android... I know just enough to make trouble, apparently. Is there something I'm missing about threading or activities? Is it perhaps something as simple as handling my activity differently?

I'd appreciate a 30,000 foot overview, and then I can provide code samples, as needed (I've gone through too many iterations to pin down one to post here for now), so sorry if I'm treading close to violating a post's best-practice.

Update: animation code

    slide = new TranslateAnimation(dm.widthPixels, -params.width, 0, 0);
    slide.setDuration(animDuration);
    slide.setRepeatCount(repititions);
    slide.setRepeatMode(Animation.RESTART);
    slide.setInterpolator(new LinearInterpolator());
    slide.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {
            msgIsScrolling = true;
        }
        @Override
        public void onAnimationEnd(Animation animation) {
            msgIsScrolling = false;
        }
        @Override
        public void onAnimationRepeat(Animation animation) {
            //nothing to do
        }
    });
    textView_message.startAnimation(slide);
Ben P.
  • 52,661
  • 6
  • 95
  • 123
csr19us
  • 105
  • 9

1 Answers1

1

My gut reaction is that "multithreaded" solutions are the wrong way to approach this problem. My first thought is:

  • Change your design so that the activity just asks the service for the "next" message to show (the activity shouldn't know about how many messages or what message index it's on, it should just show whatever message the service gives it).
  • Use an Animator.AnimatorListener's onAnimationEnd() method to re-trigger your animation.

Essentially, you'd have some method inside the activity that takes a message and starts it animating. You'd call this method both when your activity is first shown and whenever a message is done scrolling.

Since this all lives inside the activity itself, there shouldn't need to be any cleanup when the activity dies.

Ben P.
  • 52,661
  • 6
  • 95
  • 123
  • Well, my activity had to spawn some kind of thread in order for the animation to actually run. It made more sense (felt more "clean") to me to have the Activity handle its own task (like showing one or many messages). There has to be a way to do this right... either that, or you're perfectly on point and I'm not going to have a neatly-contained and clean logic trail. – csr19us Jul 20 '17 at 21:36
  • Android's animation framework shouldn't require you do spawn any threads. How are you performing the animation? – Ben P. Jul 20 '17 at 21:42
  • I guess I misunderstood you. I thought you were doing animation inside a `new Thread()` sort of call. – Ben P. Jul 20 '17 at 22:02
  • My activity's main job is scrolling text. Whenever it needs to scroll multiple text messages, it needs to iterate through a list of messages and scroll one at a time. - - it just hit me... I may try to just animate the next message when the animation end event fires? – csr19us Jul 20 '17 at 22:27
  • That's exactly what I was trying to say – Ben P. Jul 20 '17 at 22:28
  • The answer to this was to avoid multithreading altogether. There was a better and much simpler method in this case (utilizing onAnimationEnd to do the next thing, no thread or anything needed). – csr19us Jul 21 '17 at 14:49