因此,在下面发布的代码中,我有一个迭代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);
}
如果我遗漏了任何内容或您还有其他问题,请与我联系。
答案 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消息会阻止消息队列,并杀死任何违反此规则的应用程序。