4

假设我正在使用一个 if 语句来解释十种不同的可能按钮按下,这些按钮按下将事件值发送到事件侦听器:

public boolean onTouch(int v) { //this is my only listener for all ten buttons
  if(event.getAction() == MotionEvent.ACTION_DOWN){
   if(v==button_one){pool.play(bass1, 1f,1f, 1, 0, 1f);}
   if(v==button_two){pool.play(bass2, 1f,1f, 1, 0, 1f);}
   if(v==button_three){pool.play(bass3, 1f,1f, 1, 0, 1f);}
   if(v==button_four){pool.play(snare1, 1f,1f, 1, 0, 1f);}
   if(v==button_five){pool.play(snare2, 1f,1f, 1, 0, 1f);}
   if(v==button_six){pool.play(snare3, 1f,1f, 1, 0, 1f);}
   if(v==button_seven){pool.play(hh1, 1f,1f, 1, 0, 1f);}
   if(v==button_eight){pool.play(hh2, 1f,1f, 1, 0, 1f);}
 }
 return false;
}

对这些进行分类会更有效吗?说... 一个用于军鼓的 onClick 事件,一个用于贝司的事件,一个用于踩镲的事件,这样当按下按钮时,程序就不必计算每个 if 语句,只有在监听器中的那个用于触发事件?

4

6 回答 6

5

这样的事情呢?

HashMap<int,int>  soundMap = new HashMap<int,int>();
soundMap.put(button_one, bass1);
soundMap.put(button_two, bass2);
soundMap.put(button_three, bass3);
soundMap.put(button_four, snare1);
soundMap.put(button_five, snare2);
soundMap.put(button_six, snare3);
soundMap.put(button_seven, hh1);
soundMap.put(button_eight, hh2);

将 HashMap 作为类变量,并在 onCreate 或其他东西中初始化映射。然后你可以将它用于你的听众:

public boolean onTouch(int v) {
    if(event.getAction() == MotionEvent.ACTION_DOWN) {
        pool.play(soundMap.get(v), 1f, 1f, 1, 0, 1f);
    }
    return false;
}

这样做的好处是,如果以后要添加更多按钮,只需要用新的声音映射修改映射初始化方法即可;侦听器不需要任何更改。

于 2012-05-25T14:10:43.953 回答
1

只是为了在这里添加丰富的建议和意见,并同意之前关于“这真的是一个性能问题”的所有观点,我会选择使代码最容易阅读和维护的结构,以及其他任何人可能需要维护它。通过维护,还要考虑扩展它。如果您想再添加 5 个音垫,在 3 个月内会发生什么?

减少到最少的行数可能会给您带来几乎无法估量的性能提升,并在您的 APK 中节省几个字节,但在大多数情况下,我会以可读性为代价。

尽管如此,我确实喜欢 kcoppocks 的解决方案。对我来说,这很简短,我会怎么做更好,一个开关。

于 2012-05-25T14:33:15.150 回答
0

在你知道这是一个问题之前,我不会担心打破它。switch 将有助于减少重复的if语句:

public boolean onTouch(int v) {
  if(event.getAction() == MotionEvent.ACTION_DOWN) {
    switch (v) {
    case button_one: pool.play(); break;
    case button_two: pool.play(..); break;
    ...
    }
  }
 return false;
}
于 2012-05-25T14:05:53.780 回答
0

我不知道这if运行了多少次,但对我来说似乎并没有效率低下。这个布尔测试非常快。无论如何,如果您确实想让它尽可能高效,我看到两个选项:

  1. 最简单的一个:使用else if而不是if.
  2. 复杂的一个:使用一组ActionIf对象来做你想做的事:

public interface ActionIf {
    public void go();
}

public class ActionBass1 implements ActionIf {
    @Override
    public void go() {
        pool.play(bass1, 1f,1f, 1, 0, 1f);
    }
}

public class ActionBass2 implements ActionIf {
    @Override
    public void go() {
        pool.play(bass2, 1f,1f, 1, 0, 1f);
    }
}

...

public ActionIf[] actions = {new ActionBass1(), new Action Bass2(), ...);

public boolean onTouch(int v) { //this is my only listener for all ten buttons
    if(event.getAction() == MotionEvent.ACTION_DOWN && v >= 0 && v <= (button_eight-button_one)){
        actions[button_one+v].go();
    }
    return false;
}

于 2012-05-25T14:18:48.197 回答
0

在这种情况下,真的不值得担心性能;条件语句所花费的时间将被它周围的事件处理代码完全相形见绌。绩效的第一至第三定律是衡量、衡量、衡量,我对找到差异的机会持怀疑态度。

我不禁注意到唯一改变的是 pool.play 的第一个参数。bass1、bass2 等与对应的 v 值之间是否存在关系?

于 2012-05-25T14:16:23.533 回答
0

我认为没有必要,但我肯定会推荐 switch 和 case。您可以订购最常见到最不常见的,但它的变化很小,不会被注意到。通过这些 if 语句根本不需要很长时间。

于 2012-05-25T14:16:43.397 回答