我是 Android 开发新手。只是想测试以下代码,点击按钮执行一些任务。在日志显示循环结束后 Toast 弹出,因为 Toast 是异步的。但是
- 当我注释掉 Thread.sleep()(在没有 thread.sleep() 的情况下循环)时,所有 toast 都显示为 0 到 14
- 当 Thread.sleep(1000) 时,toasts 显示为 7 到 14
- 当 Thread.sleep(500) 时,toasts 显示为 3 到 14
- Thread.sleep(2000)时,只显示第14条toast
为什么会这样?据我所知,这一切都发生在 UI 线程中。如果只有一个线程,那么toast是如何异步工作的?
谢谢
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int i=0;
int j=0;
Log.d("tag", "sec "+i);
while(i++<15){
Log.d("tag", "sec "+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(),"num"+(j),Toast.LENGTH_SHORT).show();
j++;
}
}
});
最佳答案
Toast is asynchronous
首先,默认情况下 Toast 不是异步的。
why does it behave like this?
使用 Toast.LENGTH_SHORT
创建的 toast 的生命周期为 2 秒。现在,如果您的 UI 线程被锁定(因为 Thread.sleep
),则 toast 将不会出现在屏幕上。它会在显示之前“死亡”。
如何让它按预期工作
在新创建的 Thread
中运行整个 block ,并且只在主线程中创建和显示 Toast
,
你需要按照以下几行做一些事情,
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
int j = 0;
Log.d("tag", "sec " + i);
while (i++ < 15) {
Log.d("tag", "sec " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
final int finalJ = j;
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "num" + (finalJ), Toast.LENGTH_SHORT).show();
}
});
j++;
}
}
}).start();
}
});
通过使用 Handler.postDelayed
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final int[] i = {0};
final int[] j = {0};
final int delayTime = 1000;
Log.d("tag", "sec "+ i[0]);
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
@Override
public void run() {
if(i[0]++<15) {
Log.d("tag", "sec " + i[0]);
Toast.makeText(getApplicationContext(), "num" + (j[0]), Toast.LENGTH_SHORT).show();
j[0]++;
handler.postDelayed(this, delayTime);
}
}
};
handler.postDelayed(runnable, delayTime);
}
});
P.S - 切勿在主线程中使用 Thread.sleep
,它会阻塞 UI 并导致糟糕的 UX。
关于java - 使用 Thread.sleep 了解循环中的 toast,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57344531/