了解 ProgressDialog 的工作原理

Understanding how ProgressDialog works

我使用修复了 API 23 的设备,因为我认为这很容易,所以我想使用 ProgressDialog,因为它仍然可用。

我试图启动一个需要做很多工作的线程,而当他这样做时,用户必须等待。

我在使用 ProgressDialog 时遇到了不同的问题:

1。不停

public void buttun(View view) {

        ProgressDialog mProgressDialog = new ProgressDialog(this);
        mProgressDialog.show(this,"Title","Message",true);
        addCustomQueue.start();
        getCustomQueue.start();
        mProgressDialog.dismiss();
}

在这种情况下,单击按钮会显示 ProgressDialog,但 .dismiss() 不起作用。 (我知道即使线程未完成,ProgessDialog 也应立即关闭。我只是想知道 .dismiss() 是否有效。)

2。在 MainThread

上做很多工作
public void buttun(View view) {

        ProgressDialog mProgressDialog = new ProgressDialog(this);
        mProgressDialog.show(this,"Title","Message",true);
        addCustomQueue.start();
        getCustomQueue.start();

        try {
            addCustomQueue.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        mProgressDialog.dismiss();
    }

当我尝试 .join() 一个肯定会在 20 秒后结束的线程时,ProgressDialog 在大约 30 秒后出现并且 .dismiss() 也不起作用。但是我得到了关于线程正在完成的信息。

我想使用的样式是第二种,但我需要一个合适的方法来实现它。 正确的使用方法是什么?

 new Thread(new Runnable() {
        @Override
        public void run() {
            //  Here you can do your background task for processing data that may take seconds
            addCustomQueue.start();
            getCustomQueue.start();
            try {
                addCustomQueue.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }).start();

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            // Here you can put code for UI changes that display on screen
            if (mProgressDialog.isShowing()) {
                mProgressDialog.dismiss();
            }
        }
    });

您可以通过适当的多线程性能来管理它,我在这里提供示例只是因为我不了解您的功能和您的代码。

你应该在开始你的作品之前写下下面的代码:

final ProgressDialog pd = new ProgressDialog(this);
            pd.setMessage("Processing...");
            pd.setCancelable(false);
            pd.show();

在完成作品后写下: pd.cancel();

您正在创建两个 Progressdialog 对象。

//Instead of 
//ProgressDialog mProgressDialog = new ProgressDialog(this);
//mProgressDialog.show(this,"Title","Message",true);

//use
ProgressDialog mProgressDialog = ProgressDialog.show(this,"Title","Message",true);

//Now, you'll be able to dismiss it
mProgressDialog.dismiss();

这不是最直观的方法,但静态 show(..) 方法创建并显示进度对话框。 (Reference)

static ProgressDialog show(Context context, CharSequence title, CharSequence message, boolean indeterminate)

Creates and shows a ProgressDialog.

P.S - Reyhane 的回答也应该有效,因为 show() 方法是一种对象级方法,它直接显示对话框而不是创建对话框并显示。 (Reference)

1。不停

其实ProgressDialog.show(Context, String, String, boolean)是一个静态方法,它会创建一个新的ProgressDialog并return显示它

您应该像这样更改您的代码。

ProgressDialog mProgressDialog = ProgressDialog.show(this,"Title","Message",true);
mProgressDialog.dismiss();

2。 MainThread

上的工作太多

你应该永远不会阻止Android的MainThread,所以在MainThread上加入一个线程不是一个好主意。

您可以在 MainThread 上使用 Handler 到 post 回调,而不是在 MainThread 上加入 long-running 线程。

你的Activity:

public class MainActivity extends AppCompatActivity {

    private ProgressDialog mProgressDialog;
    private AddCustomQueueThread addCustomQueue;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        addCustomQueue = new AddCustomQueueThread(this);
    }

    public void dismissProgressDialog() {
        if(mProgressDialog != null) {
            mProgressDialog.dismiss();
            mProgressDialog = null;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(mProgressDialog != null) {
            mProgressDialog.dismiss();
            mProgressDialog = null;
        }
    }

    public void button(View view) {
        addCustomQueue.start();
        mProgressDialog = ProgressDialog.show(this,"Title","Message",true);
    }
}

您的话题:


    class AddCustomQueueThread extends Thread {
        final WeakReference<MainActivity> activity;
        final Handler handler;
        AddCustomQueueThread(MainActivity act) {
            activity = new WeakReference<>(act);
            handler = new Handler(Looper.getMainLooper());
        }

        @Override
        public void run() {
            super.run();

            //do your work.

            handler.post(new Runnable() {
                @Override
                public void run() {
                    MainActivity act = activity.get();
                    if(act != null) {
                        act.dismissProgressDialog();
                    }
                }
            });

        }
    }

请注意:我们将对 activity 的引用存储在弱引用中,这是为了防止泄漏您的 activity.