for循环中的Thread.sleep导致循环体问题

时间:2014-01-15 13:10:29

标签: java android loops sleep

因此,在下面发布的代码中,我有一个迭代10次的for循环,for循环的目标是每0.5秒创建10次相同的ImageView。当我测试它时,它在5秒后同时添加了所有内容(假设因为它经过循环并等待500ms再次通过它,500ms * 10 = 5秒)。

事情是,为什么它在循环中等待500ms 10次然后在for循环中完成剩下的所有事情。

我添加了一条Log.i打印消息,看看是否会同时打印,如果我的线程或循环出现问题,并且每隔500毫秒打印一条消息。我不明白为什么它每500ms执行一次Log.i消息,但循环内的其余代码是在它们位于相同的括号中并且都在Thread.sleep方法之前完成的。

谢谢! 码: 主要代码(错误在btnRoundsClick方法内)

    Variables var = new Variables();
EntityActions e = new EntityActions();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    final Window window = getWindow();
    window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.firstmap);
    FontTextView username = (FontTextView) findViewById(R.id.lblUsername);
    username.setText("NAME");
    RelativeLayout map1 = (RelativeLayout) findViewById(R.id.map1); 
    e.setMap(map1);
}

// On click of button, add enemies
public void btnRoundsClick(View view) {
    ImageView firetower[] = new ImageView[10];
    for (int c = 0; c < 10; c++) {
         try
                {
                firetower[c] = new ImageView(Start.this);
                  firetower[c].setImageResource(R.drawable.firetower);
                e.setEnemy(firetower[c]);
                e.setStartEnd(0, 0, 0, 198);
                e.addEnemy();
                e.followPath();
                Log.i("There  is 1 ", "more ImageView");
                Thread.sleep(500);
            } catch (Exception e)
            {
                e.printStackTrace();
            }
    }
}

EntityActions类     ImageView敌人;     int startX,startY,endX,endY;     RelativeLayout地图;

public EntityActions() {
    startX = 0;
    endX = 0;
    startY = 0;
    endY = 0;
}

public void setEnemy(ImageView enem) {
    enemy = enem;
}

public void setMap(RelativeLayout m) {
    map = m;
}

public void addEnemy() {
    map.addView(enemy);
    enemy.getLayoutParams().height = 60;
    enemy.getLayoutParams().width = 60;
    RelativeLayout.LayoutParams head_params = (RelativeLayout.LayoutParams)enemy.getLayoutParams();
    head_params.setMargins(30, -20, 0, 0); //substitute parameters for left, top, right, bottom
    enemy.setLayoutParams(head_params);
}

public void setStartEnd(int xS, int xE, int yS, int yE) {
    startX = xS;
    endX = xE;
    startY = yS;
    endY = yE;
}

public void followPath() {
    TranslateAnimation animation = new TranslateAnimation(startX, endX, startY, endY);
    animation.setDuration(6000);
    animation.setFillAfter(true);
    ((View) enemy).startAnimation(animation);
}

如果我遗漏了任何内容或您还有其他问题,请与我联系。

3 个答案:

答案 0 :(得分:4)

  

事情是,为什么它在循环中等待500ms 10次然后在for循环中完成剩下的所有事情。

没有。它执行循环的迭代,每500ms执行一次 - 然后然后允许UI线程实际显示更新。在循环中添加一些日志记录,您将看到“每500毫秒一次迭代”行为。

基本上,你正在阻止UI线程。不要那样做。

阅读Android Processes and Threads guide了解更多详情和替代方案。

答案 1 :(得分:0)

你不能使用简单的计时器吗?

new Timer().scheduleAtFixedRate(new TimerTask() {

@Override
                public void run() {
//Your code here...
}

}, 0, 500);

像这样......

答案 2 :(得分:0)

您正在一个循环中进行所有UI更改,在每次UI更改后您都没有从btnRoundsClick(View view)返回,因此您不会给予android系统处理和可视化您的更改的机会。 android中的UI主要基于消息。您的btnRoundsClick方法在此类消息中执行,在更改UI后,另一条消息将显示您的更改。

您可以通过多种方式修复它,例如使用Handler类,您可以:

Handler handler = new Handler(); // as a class field

然后在你的btnRoundsClick(View view)handler.postDelayed( /*here runnable that does UI changes*/ )中,在这个可以安排下一个Runnable的runnable中,你可以保留一些保留重绘次数的类变量。


另一件事是,你不应该在UI线程上执行Thread.sleep,这可能会在几秒钟后导致ANR(应用程序没有响应)错误。 Android确保没有UI消息会阻止消息队列,并杀死任何违反此规则的应用程序。

相关问题