CompEng
CompEng

Reputation: 7376

Why the process is not running on background?

I have a XX method which takes 2 seconds. I want to do something before it and when XX method finishes I want to do another thing.

The problem is:

It works fine but the problem is everything does when the XX method finish , I mean the method which must run before XX and the method which must run after XX work togeter after XX method finish.

What I did is:

runOnUiThread(new Runnable() {
                 @Override
                 public void run() {
                     beforeXX();
                }
            }); 

XX();//takes 2 seconds   

runOnUiThread(new Runnable() {
                 @Override
                 public void run() {
                     afterXX();
                }
            });

afterXX(); and beforeXX(); are both of them are change the view. (I also tried AsyncTask method)

thanks in advance

Upvotes: 0

Views: 159

Answers (2)

nerdwaller
nerdwaller

Reputation: 1863

Moved from comment

I think you might be creating a race condition there, because beforeXX may or may not finish before xx() is even called, and given the naming - before needs to be run completely before xx starts. Then xx blocks until you're done. An AsyncTask is definitely a better approach.

Take for example:

// The three generics here are: 
// 1) What is passed into doInBackground (invoked via .execute())
// 2) onProgressUpdate params (I didn't include that)
// 3) What is passed into onPostExecute
public class DoMyBackendWork extends AsyncTask<String, Void, String> {
    @Override
    protected void onPreExecute() {
        // do beforeXX(); stuff here, this runs on the UI thread
    }

    @Override
    protected String doInBackground(String... filePaths) {
        // do the xx(); code here.  It will be sequential, such as:
        // data = expensiveSetup();
        // procData = processData(data);
        // expensivePostDataThatCanBeDoneInBackground(procData);
        // return strings...;  This goes to onPostExecute
    }

    @Override
    protected void onPostExecute(String result) {
        // do afterXX(); stuff here, this runs on the UI thread
        // this data comes from the return of doInBackground
    }
    private void expensiveSetup() {}
    private ProcessedData processData(Data data) {}
    private void expensivePostDataThatCanBeDoneInBackground(ProcessedData data) {}
}

Then in wherever you are calling that from:

DoMyBackendWork dmbw = new DoMyBackendWork(/* add ctor and params if needed */);
dmbw.execute(/* string params */);

Upvotes: 2

webuster
webuster

Reputation: 2510

Why not simply run the code in the lines of

beforeXX();
XX();
afterXX();

?

What you wrote is not guaranteed to be executed in the order that your code is written and in the way you expect, because thread management belongs to the operating system and not to you as a programmer.

The least you can do to solve your problem is to wait for the threads beforeXX and afterXX to finish. First thing I'm thinking of is use an Object as a lock and syncrhonize your threads on it. If you don't know how to do that, ask and I'll update my answer.

Upvotes: 0

Related Questions