为什么Toast在时间段结束后没有被隐藏?
Why is the Toast not hidden after the time period ended?
我创建了一个使用下载管理器下载文件的小应用程序。
目前一切正常。
我想添加一个小 Toast
并向用户显示当前下载状态。
所以我做了类似下面的事情:
Thread t = new Thread(new Runnable() {
@Override
public void run() {
int status = -1;
while ( (status = checkDownloadStatus()) != -1 && status != DownloadManager.STATUS_FAILED && status != DownloadManager.STATUS_SUCCESSFUL) {
try {
Log.d("MyApp", "Sleeping for 500 while polling for status [ " + status + " ]");
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
Log.e("MyApp", e.getLocalizedMessage());
}
}
Log.d("MyApp", "Stop sleeping!");
}
});
t.start();
在 checkDownloadStatus
中,我向用户显示 Toast
下载状态:例如STARTED/PENDING/FINISHED
我看到下载正在进行中,我在下载过程中看到 Toast
,在日志中我看到:
Sleeping for 500 while polling for status [ 2 ]
Sleeping for 500 while polling for status [ 2 ]
Sleeping for 500 while polling for status [ 2 ]
Sleeping for 500 while polling for status [ 2 ]
…..
然后当下载完成后我在日志中看到:
Stop sleeping!
但是 Toast
最后一条消息仍然显示。
我做错了什么?有没有更好的方法来实现我所需要的
更新:
private int checkDownloadStatus() {
final Cursor c= dm.query(new DownloadManager.Query().setFilterById(downloadId));
if (c == null) {
showUserStatus(getActivity().getString(R.string.download_not_found), Toast.LENGTH_LONG);
}
else {
c.moveToFirst();
final int status = showStatusMessage(c);
c.close();
return status;
}
return -1;
}
private int showStatusMessage(Cursor c) {
String msg="???";
int downloadStatus = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
switch (downloadStatus) {
case DownloadManager.STATUS_FAILED:
msg= getActivity().getString(R.string.download_failed);
break;
case DownloadManager.STATUS_PAUSED:
msg= getActivity().getString(R.string.download_paused);
break;
case DownloadManager.STATUS_PENDING:
msg= getActivity().getString(R.string.download_pending);
break;
case DownloadManager.STATUS_RUNNING:
msg= getActivity().getString(R.string.download_in_progress);
break;
case DownloadManager.STATUS_SUCCESSFUL:
msg= getActivity().getString(R.string.download_complete);
break;
default:
msg= getActivity().getString(R.string.download_is_nowhere_in_sight);
break;
}
showUserStatus(msg, Toast.LENGTH_LONG);
return downloadStatus;
}
private void showUserStatus(final String msg, final int length) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getActivity(), msg, length).show();
}
});
}
看,您正在 while 循环条件中调用 checkDownloadStatus() 方法,因此它将被一次又一次地调用,直到条件不满足为止。这就是吐司一次又一次出现的原因。 Toast会在隐藏最后一次显示之前再次显示,所以它看起来显示了很长时间。(抱歉英语不好)
Toast 已排队。如果您使用相同的文本调用 showText n 次,您将在 n * 长度的时间内看到具有相同文本的吐司。保留对当前 Toast
的引用并在显示下一个之前调用 Toast.cancel()。
例如
Toast mToast;
private void showUserStatus(final String msg, final int length) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (mToast != null) {
mToast.cancel();
}
mToast = Toast.makeText(getActivity(), msg, length);
mToast.show();
}
});
}
不要为此使用 while 循环,请改用 Timer
Timer mtimer = new Timer ();
mtimer.schedule (new TimerTask () {
@Override
public void run () {
if( (status = checkDownloadStatus()) != -1 && status != DownloadManager.STATUS_FAILED && status != DownloadManager.STATUS_SUCCESSFUL){
try {
Log.d("MyApp", "Sleeping for 500 while polling for status [ " + status + " ]");
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
Log.e("MyApp", e.getLocalizedMessage());
}
}
}
}, 0, 1000);
每 1 秒运行
我创建了一个使用下载管理器下载文件的小应用程序。
目前一切正常。
我想添加一个小 Toast
并向用户显示当前下载状态。
所以我做了类似下面的事情:
Thread t = new Thread(new Runnable() {
@Override
public void run() {
int status = -1;
while ( (status = checkDownloadStatus()) != -1 && status != DownloadManager.STATUS_FAILED && status != DownloadManager.STATUS_SUCCESSFUL) {
try {
Log.d("MyApp", "Sleeping for 500 while polling for status [ " + status + " ]");
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
Log.e("MyApp", e.getLocalizedMessage());
}
}
Log.d("MyApp", "Stop sleeping!");
}
});
t.start();
在 checkDownloadStatus
中,我向用户显示 Toast
下载状态:例如STARTED/PENDING/FINISHED
我看到下载正在进行中,我在下载过程中看到 Toast
,在日志中我看到:
Sleeping for 500 while polling for status [ 2 ]
Sleeping for 500 while polling for status [ 2 ]
Sleeping for 500 while polling for status [ 2 ]
Sleeping for 500 while polling for status [ 2 ]
…..
然后当下载完成后我在日志中看到:
Stop sleeping!
但是 Toast
最后一条消息仍然显示。
我做错了什么?有没有更好的方法来实现我所需要的
更新:
private int checkDownloadStatus() {
final Cursor c= dm.query(new DownloadManager.Query().setFilterById(downloadId));
if (c == null) {
showUserStatus(getActivity().getString(R.string.download_not_found), Toast.LENGTH_LONG);
}
else {
c.moveToFirst();
final int status = showStatusMessage(c);
c.close();
return status;
}
return -1;
}
private int showStatusMessage(Cursor c) {
String msg="???";
int downloadStatus = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
switch (downloadStatus) {
case DownloadManager.STATUS_FAILED:
msg= getActivity().getString(R.string.download_failed);
break;
case DownloadManager.STATUS_PAUSED:
msg= getActivity().getString(R.string.download_paused);
break;
case DownloadManager.STATUS_PENDING:
msg= getActivity().getString(R.string.download_pending);
break;
case DownloadManager.STATUS_RUNNING:
msg= getActivity().getString(R.string.download_in_progress);
break;
case DownloadManager.STATUS_SUCCESSFUL:
msg= getActivity().getString(R.string.download_complete);
break;
default:
msg= getActivity().getString(R.string.download_is_nowhere_in_sight);
break;
}
showUserStatus(msg, Toast.LENGTH_LONG);
return downloadStatus;
}
private void showUserStatus(final String msg, final int length) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getActivity(), msg, length).show();
}
});
}
看,您正在 while 循环条件中调用 checkDownloadStatus() 方法,因此它将被一次又一次地调用,直到条件不满足为止。这就是吐司一次又一次出现的原因。 Toast会在隐藏最后一次显示之前再次显示,所以它看起来显示了很长时间。(抱歉英语不好)
Toast 已排队。如果您使用相同的文本调用 showText n 次,您将在 n * 长度的时间内看到具有相同文本的吐司。保留对当前 Toast
的引用并在显示下一个之前调用 Toast.cancel()。
例如
Toast mToast;
private void showUserStatus(final String msg, final int length) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (mToast != null) {
mToast.cancel();
}
mToast = Toast.makeText(getActivity(), msg, length);
mToast.show();
}
});
}
不要为此使用 while 循环,请改用 Timer
Timer mtimer = new Timer ();
mtimer.schedule (new TimerTask () {
@Override
public void run () {
if( (status = checkDownloadStatus()) != -1 && status != DownloadManager.STATUS_FAILED && status != DownloadManager.STATUS_SUCCESSFUL){
try {
Log.d("MyApp", "Sleeping for 500 while polling for status [ " + status + " ]");
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
Log.e("MyApp", e.getLocalizedMessage());
}
}
}
}, 0, 1000);
每 1 秒运行