Java/Android等待线程完成后再运行新方法



我有一个android应用程序(用java编写),它有两个按钮(连接请求数据)。

单击每个按钮后,将执行一项任务,并显示进度对话框,以显示任务完成的程度。

为了显示进度对话框,单击每个按钮时,任务将在线程上运行。

connect按钮只有一个任务-在线程上运行。但是,请求数据按钮执行两个任务-线程上的第一个任务类似于连接按钮,但还有第二个任务refreshInfo(),该任务必须在线程上的progThread第一个任务完成后运行。

private Button connectButton;
private Button requestDataButton;
private ProgressDialog connectionDialog;
private ProgressDialog requestDataDialog;
private ProgressThread progThread;
private int currentDialog;
public void connectClick(View view)      //When the connect button is clicked
{
    performAction(1);   //Run the thread to perform the action
}
public void requestDownloadClick(View view)   //When the request data button is clicked
{
    performAction(2);    //Run the thread to perform the action
    refreshInfo();    //Do something else
}
private void performAction(int type)
{
    currentDialog = type;
    showDialog(type);
    try 
    {
        progThread.join();
    } 
    catch (InterruptedException e) 
    {
        e.printStackTrace();
    }
}

这里的关键方法是执行操作(int类型)。我基本上不希望这个方法在progThread完成运行之前完成。

正如你所看到的,我已经尝试了progThread.join()来阻止该方法继续运行,直到progThread完成运行,但是由于progThread及显示进度对话框,运行Progress.join,当前,当您单击该按钮时,第一个任务正在执行,但对话框只在最后闪烁。

有人能想出一种运行线程的方法吗?正常显示Progress Dialog,然后运行第二个方法(如果有)。

我已经包含了下面的线程代码,以备不时之需。

private class ProgressThread extends Thread 
{   
    final static int DONE = 0;
    final static int RUNNING = 1;   // Class constants defining state of the thread
    private Handler progressHandler;
    int mState;
    int total;
    ProgressThread(Handler _handler)    // Constructor with an argument that specifies Handler on main thread to which messages will be sent by this thread.
    {
        progressHandler = _handler;
    }
    public void run()    // Invoked automatically when the Thread starts.  
    {
        mState = RUNNING;   
        updateProgressBar();
        connectButton = (Button) findViewById(R.id.btnConnect);
        requestDataButton = (Button) findViewById(R.id.btnRequestDownload);
        while (mState == RUNNING) 
        {
            if (currentDialog == 1)
            {
                try
                { 
                    doSomething();
                    if (something)
                    {
                        setState(DONE);
                        total = 100;
                        updateProgressBar();
                        removeDialog(1);
                        connectButton.setEnabled(false);
                    }
                    else
                    {
                        total = total + 20;
                        if (something has reached a limit)
                        {
                            setState(DONE);
                            total = 0;
                            updateProgressBar();
                            removeDialog(1); 
                        }
                    }
                    updateProgressBar();
                }
                catch (Exception e)
                {
                }
            }
            if (currentDialog == 2)
            {
                try
                {
                    doSomething();
                    total = 10;
                    updateProgressBar();
                    doSomething();
                    total = 70;
                    updateProgressBar();
                    if (something)  //If the download info has not been got
                    {
                        setState(DONE);
                        total = 0;
                        updateProgressBar();
                        removeDialog(2);
                        runOnUiThread(new Runnable()
                        {
                            public void run() 
                            {
                                connectButton.setEnabled(true);
                                requestDataButton.setEnabled(true);
                            }                               
                        });  
                    } 
                    else
                    {
                        total = 100;
                        updateProgressBar();
                        setState(DONE);
                        removeDialog(2);
                        runOnUiThread(new Runnable()
                        {
                            public void run() 
                            {
                                requestDataButton.setEnabled(false);
                            }                               
                         }); 
                     }
                }
                catch (Exception e)
                {
                    removeDialog(2);
                    setState(DONE);
                    runOnUiThread(new Runnable()
                    {
                        public void run() 
                        {
                            connectButton.setEnabled(true);
                            requestDataButton.setEnabled(true);
                        }                               
                    });  
                }
            }
        }
    }
    // Set current state of thread (use state=ProgressThread.DONE to stop thread)
    public void setState(int state) 
    {
        mState = state;
    }
    public void updateProgressBar()
    {
        Message msg = progressHandler.obtainMessage();   // Send message (with current value of  total as data) to Handler on UI thread so that it can update the progress bar
        Bundle b = new Bundle();
        b.putInt("total", total);
        msg.setData(b);
        progressHandler.sendMessage(msg);
    }
}
final Handler handler = new Handler()     // Handler on the main (UI) thread that will receive messages from the second thread and update the progress.
{
    public void handleMessage(Message msg) 
    {
        int total = msg.getData().getInt("total");             // Get the current value of the variable total from the message data and update the progress bar
        switch (currentDialog)
        {
        case 1 : 
            connectionDialog.setProgress(total);
            break;
        case 2 : 
            requestDataDialog.setProgress(total);
            break;
        }
    }
};
protected Dialog onCreateDialog(int id) 
{   
    switch (currentDialog)
    {
    case 1 :
        connectionDialog = new ProgressDialog(this);
        connectionDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        connectionDialog.setMax(100);
        connectionDialog.setProgress(0);
        connectionDialog.setMessage("Connecting To The Device");
        progThread = new ProgressThread(handler);
        progThread.start();
        return connectionDialog;
    case 2 :
        requestDataDialog = new ProgressDialog(this);
        requestDataDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        requestDataDialog.setMax(100);
        requestDataDialog.setProgress(0);
        requestDataDialog.setMessage("Requesting Download Data");
        progThread = new ProgressThread(handler);
        progThread.start();
        return requestDataDialog;
    default : 
        return null;
    }
}

Android API提供了一个AsyncTask类,该类有两个方法doInBackgroundonPostExecute。您必须覆盖它们,在doInBackground中执行任何必须执行的操作,并且当作业完成时,将运行onPostExecute回调。还有一个onProgressUpdate回调,这正是您所需要的。

查看AsyncTask类。它应该能够做你想做的事。

http://developer.android.com/reference/android/os/AsyncTask.html

似乎还有其他答案。AsyncTask是前进的方向。

但是,如果您想推进线程实现,只需在第一个线程的运行方法结束时start()下一个线程即可。

听起来您需要使用大小为1 的Countdown Latch

相关内容

最新更新