Reputation: 7749
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:
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?
Upvotes: 0
Views: 448
Reputation: 16560
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.
Upvotes: 0
Reputation: 3210
Have you looked at Observer and Observable? Maybe your observed model can perform the update using Runnable and then notify the observer.
Upvotes: 1