简体   繁体   中英

Wait for AsyncTask to finish

Hi I'm making Login page that access MySQL database. But my Activity always runs the code that check fail/success before it finishes the AsyncTask .

I tried using asynctask.get() method, but it just freeze my UI and doesn't work.

I tried this answer that said I should call the result-checker method inside onPostExecute() .

But since I need to change the TextView to show success/failed, it results in NullPointerException because I instantiate the TextView inside onCreate() .

I can't move the TextView instantiation into constructor because it will return NullPointerException unable to instantiate activity ComponentInfo .

Login.java

public class Login extends Activity{

    //declare global Views here

    protected void onCreate(Bundle bundle){
        //Setup views
    }

    protected void onClick(View v){
        //Setup necessary variables
        AsyncClass async = new AsyncClass(this);
        async.execute(username, password);
    }

    public void checkSuccess(boolean success){
        if(success)
            textView1.setText("Success");
        else
            textView1.setText("Failed");
    }
}

AsyncClass.java

public class AsyncClass extends AsyncTask<String, String, JSONObject>{
    protected JSONObject doInBackground(String... params){
        //access database
    }

    protected void onPostExecute(JSONObject json){
        //read the json result
        Login login = new Login();
        login.checkSuccess(true);
    }
}

Any solution? Thanks

How about making AsyncTask as your inner class?

So your code should look something like below.

public class Login extends Activity {

    //declare global Views here

    protected void onCreate(Bundle bundle) {
        //Setup views
    }

    protected void onClick(View v) {
        new AsyncClass().execute(username, password);
    }

    public void checkSuccess(boolean success) {
        if (success) textView1.setText("Success");
        else textView1.setText("Failed");
    }

    class AsyncClass extends AsyncTask < String, String, JSONObject > {
        protected JSONObject doInBackground(String...params) {
            //access database
        }

        protected void onPostExecute(JSONObject json) {
            checkSuccess(true / false);
        }
    }
}

try this

protected void onPostExecute(JSONObject json){
    //read the json result
    Login login = (Login)context; // object that you pass to task constructor
    login.checkSuccess(true);
}

Also you can add progress dialog to your task to indicate some job execution

public class BaseTask<T> extends AsyncTask<Object, Void, T> {

public Context context;
public ProgressDialog dialog;

public BaseTask(Context context) {
    this.context = context;
    this.dialog = new ProgressDialog(context);
}

@Override
protected void onPreExecute() {
    this.dialog.setMessage(context.getResources().getString(R.string.loading));
    this.dialog.show();

}

@Override
protected T doInBackground(Object... objects) {
    //....
    return something;
}

@Override
protected void onPostExecute(T result) {
    if (dialog != null && dialog.isShowing())
        dialog.dismiss();
    // do something
}

}

You cannot edit the UI from the async task thread. In order to make updates to the UI thread, use the onProgressUpdate() method. This method is part of your AsyncTask class, is actually executed in the main UI Thread (I hope you use the async task as a nested class btw, since it is declared public I guess your not. You should change that). The onProgressUpdate() Method is called by the OS itself if you call publishProgress(...) inside your Async task.

A small sample:

protected JSONObject doInBackground(String... params){
    publishProgress("test");
}

    /**
     * This method is part of the Async Task
     */
    protected void onProgressUpdate(String... progress) {
        login.checkSuccess(true);
    }   

I would use it this way, just override your onPostExecute where you need it or create a own interface

//create a object f your asyncclass and 
//override the onPostExecute where you need it
mInfo = new ASYNCCLASS({
   @Override
   public void onPostExecute(Object result){
      //doSomething something with your views!

  }
}).execute();

Waiting is not the answer, because you do not know how long your Asynctask will take to end. Code above is not tested, just pseudoce, but it should show what i mean.

Do not have my IDE round here, so if anybody would correct the brackets if neccessary would be great!

Greetz

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM