Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java / Android wait until a thread has finished before running a new method

I have an android application (written in java) which has two buttons (connect and request data).

When each button is clicked, a task is performed and a progress dialog appears to display how much the task has completed.

In order to show the progress dialog, when each button is clicked, the task is run on a thread.

The connect button just has one task - run on the thread. However, the request data button executes two tasks - the first task on the thread similar to the connect button but also a second task, refreshInfo() which must be run after the first task on the thread, progThread is finished.

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

The key method here is performAction(int type). I basically don't want this method to complete until progThread has finished running.

As you can see, I've tried progThread.join() to prevent the method from continuing until progThread has finished running, however as progThread involves displaying a Progress Dialog, running progThread.join() seems to prevent the Progress Dialog from showing, as currently when you click the button, the first task is performing but the dialog only flashes up at the end.

Can anyone think of a way to run the thread, showing the Progress Dialog as normal and then running the second method (if there is one).

I've included the thread code below incase it is needed.

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;
    }
}
like image 910
Pippa Rose Smith Avatar asked Feb 19 '23 16:02

Pippa Rose Smith


1 Answers

Android API provides an AsyncTask class which has two methods doInBackground and onPostExecute. You'll have to override both of them, do whatever you have to do in doInBackground and when the job is done onPostExecute callback will be run. There's also an onProgressUpdate callback which is exactly what you need.

like image 67
devmiles.com Avatar answered Mar 13 '23 04:03

devmiles.com