Question

So, I've been working on an app that has a Plan model with a number of different inputs and outputs, and the layout of the app has slider controls for the inputs and labels for the outputs. When an input changes, it updates the model, which then runs a calculation, and then updates the views. I didn't think there was anything wrong with this architecture at first, but even simple calculations seem to run really slowly, blocking the UI thread. Granted, I do have a somewhat complicated way of updating things:

  1. Slider (in a viewgroup subclass) updates its value and sends a message to a delegate (which implements an interface specific to that viewgroup subclass).
  2. Delegate (which holds the model and the control subviews) tells the Plan instance to set a new value, which triggers the plan to recalculate its outputs.
  3. Once the plan finishes its calculations, it sends another message to the delegate, which then tells its output views to update with the new values.

I've modeled this architecture off of an iOS app that I developed which didn't seem to have as big of a problem running the calculations.

Now, I know that Android is significantly different than iOS, so I'm wondering if I'm going about this completely wrong. Is there a way to just tell these views to watch the Plan model for changes and then grab the value it's supposed to display?

Another major issue that I'm seeing here is with the slider input. If I put the model update calculations into a thread, every time the slider changes, a new thread will be created. These threads (as I've seen) will more or less finish in random order, updating the view in such a way as too make very little sense when you should see incremental changes. Is there a good way of threading calculations that are supposed to be changeable with a seekbar?

Was it helpful?

Solution

Have you looked at Observer and Observable? Maybe your observed model can perform the update using Runnable and then notify the observer.

OTHER TIPS

This is just an idea of the top of my head:

Instead of just starting a new thread for each update from the slider, you could implement some kind of Queue.

You would need a to have a Thread running, that holds the Queue.

public class QueueThread extends Thread {
  private boolean running;
  private ArrayDeque<Runnable> queue;
  private Thread current;

  public QueueThread() {
    running = true;
    queue = new ArrayDeque<Runnable>();
    current = new Thread();
  }

  @Override
  public void run() {
    while( running ) {
      if( !queue.isEmpty() && !current.isAlive() ) { //We only want to start a new thread if there is one or more in the queue AND the old task is not runnning.
        current = new Thread( queue.pollFirst() );
        current.start();
      }
      else
        try {
          Thread.sleep( 200 ); //We need a sleep in order to not hammer the CPU.
        }
        catch( InterruptedException e ) {
          e.printStackTrace();
        }
    }
  }

  public void stopThread() {
    running = false;
  }

  public void add( Runnable task ) {
    queue.addLast( task ); //Here is where we add a task to the queue. The slider (or whoever posts the updates) must have a reference to this thread object.
  }
}

Doing this would allow each update to finish before the next is started. I am not sure how it will do in performance. I haven't tested it or anything. It was just an idea.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top