Java 使用SeekBar更新Android布局中的计算值
所以,我一直在开发一个应用程序,它有一个包含许多不同输入和输出的计划模型,应用程序的布局有输入的滑块控件和输出的标签。当输入发生更改时,它会更新模型,然后模型会运行计算,然后更新视图。起初我并不认为这种架构有什么问题,但即使是简单的计算也似乎运行得很慢,阻塞了UI线程。当然,我确实有一种比较复杂的更新方式:Java 使用SeekBar更新Android布局中的计算值,java,android,android-layout,seekbar,android-input-method,Java,Android,Android Layout,Seekbar,Android Input Method,所以,我一直在开发一个应用程序,它有一个包含许多不同输入和输出的计划模型,应用程序的布局有输入的滑块控件和输出的标签。当输入发生更改时,它会更新模型,然后模型会运行计算,然后更新视图。起初我并不认为这种架构有什么问题,但即使是简单的计算也似乎运行得很慢,阻塞了UI线程。当然,我确实有一种比较复杂的更新方式: Slider(在viewgroup子类中)更新其值并向委托发送消息(委托实现了特定于该viewgroup子类的接口) 委托(保存模型和控件子视图)告诉计划实例设置一个新值,这将触发计划重新计
也许您观察到的模型可以使用执行更新,然后通知观察者 这只是我脑海中的一个想法: 您可以实现某种类型的更新,而不只是为滑块的每次更新启动一个新线程 您需要一个运行的
线程,该线程包含队列
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.
}
}
公共类队列线程扩展线程{
私有布尔运行;
专用数组队列;
私有线程电流;
公共队列线程(){
运行=真;
queue=new ArrayDeque();
当前=新线程();
}
@凌驾
公开募捐{
(跑步时){
如果(!queue.isEmpty()&&&!current.isAlive()){//我们只希望在队列中有一个或多个线程且旧任务未运行时启动新线程。
当前=新线程(queue.pollFirst());
current.start();
}
其他的
试一试{
Thread.sleep(200);//为了不影响CPU,我们需要睡眠。
}
捕捉(中断异常e){
e、 printStackTrace();
}
}
}
公共void stopThread(){
运行=错误;
}
公共void添加(可运行任务){
queue.addLast(task);//这里是向队列添加任务的地方。滑块(或发布更新的人)必须有对此线程对象的引用。
}
}
这样做将允许每个更新在下一个更新开始之前完成。我不确定它的性能如何。我还没有测试过。这只是一个想法。为了真正了解导致性能问题的原因,我建议在Eclipse中的DDMS中使用分配跟踪器:。在我脑海中,听起来你需要使用带有游戏循环的SurfaceView来更新视图。这看起来确实是对我的代理模式的改进,但我不确定它是否解决了使用滑块实时更新模型的问题。问题是,当滑块移动时,或多或少会发生连续的更改,因此将计算代码推送到线程中会产生任意数量的新线程,这些线程都会以几乎随机的顺序或多或少地更新+1表示可观察,但滑块的性能问题仍然存在。更新了问题以强调滑块问题。由于我从未见过UI线程上更新值的问题,您是否尝试检查重新计算其值需要多长时间?有了适当的体系结构,这将是更新UI所需的最短时间(最佳情况)。在那之后,我想到的另一件事就是尽可能实时地更新UI,就是在另一个线程上使用队列,这样你就不会不断产生新线程,而更新是按顺序进行的。即使在这种情况下,它所花费的时间也不会比上面少。就本项目而言,您是对的,除非我实现某种队列生成/剔除算法,否则情况不会因为更新方法的执行时间而得到改善。Observer/observable无疑是对代理设计的改进。事实证明,在我的更新方法中有一个函数调用,它导致了巨大的性能损失,从而降低了UI响应速度,删除它可以让一切顺利进行,所以我将重新设计我的更新方法,希望所有的更新都能顺利完成。优化更新算法将是另一个非常好的问题,实际上:)祝你好运!