使用 Thread.sleep 了解循环中的 toast
Understanding the toast in a loop using Thread.sleep
我是 Android 开发的新手。只是想测试以下代码,点击按钮执行一些任务。在日志显示循环结束后 Toast 弹出,因为 Toast 是异步的。但是
- 当我注释掉 Thread.sleep()(在没有 thread.sleep() 的情况下循环)时,所有 toasts 都显示为 0 到 14
- 当 Thread.sleep(1000) 时,祝酒词从 7 点到 14 点显示
- 当 Thread.sleep(500) 时,祝酒词从 3 点到 14 点显示
- 当Thread.sleep(2000)时,只显示第14条吐司
为什么会这样?据我所知,这一切都发生在 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 将不会出现在屏幕上。在显示之前它会 'die'。
如何让它按预期工作
运行 新创建的 Thread
中的整个块,并且只在主线程中创建和显示 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 并导致糟糕的用户体验。
我是 Android 开发的新手。只是想测试以下代码,点击按钮执行一些任务。在日志显示循环结束后 Toast 弹出,因为 Toast 是异步的。但是
- 当我注释掉 Thread.sleep()(在没有 thread.sleep() 的情况下循环)时,所有 toasts 都显示为 0 到 14
- 当 Thread.sleep(1000) 时,祝酒词从 7 点到 14 点显示
- 当 Thread.sleep(500) 时,祝酒词从 3 点到 14 点显示
- 当Thread.sleep(2000)时,只显示第14条吐司
为什么会这样?据我所知,这一切都发生在 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 将不会出现在屏幕上。在显示之前它会 'die'。
如何让它按预期工作
运行 新创建的 Thread
中的整个块,并且只在主线程中创建和显示 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 并导致糟糕的用户体验。