为什么在时间段结束后没有隐藏Toast?

时间:2015-04-22 09:32:05

标签: java android multithreading android-download-manager android-toast

我创建了一个使用下载管理器下载文件的小应用程序 到目前为止一切都还不错。
我想添加一个小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 /等待/完成

我看到下载正在进行中,我在下载过程中看到了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();
            }
        });
    }

3 个答案:

答案 0 :(得分:1)

Toast排队。如果您使用相同的文本n次调用showText,您将看到n * length时间内具有相同文本的Toast。保留对当前Toast的引用,并在显示下一个之前调用Toast.cancel()。

E.g。

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();
            }
        });
    }

答案 1 :(得分:1)

不要使用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秒后运行

答案 2 :(得分:0)

请参阅,您在while循环条件中调用checkDownloadStatus()方法,因此将一次又一次地调用它,直到条件不满足。这就是吐司一次又一次地出现的原因。 Toast会在隐藏最后一次显示之前再次显示,所以它看起来很长时间。(对不起英语不好)