-->

Android return value in AsyncTask onPostExecute us

2019-03-05 13:18发布

问题:

This question already has an answer here:

  • Android AsyncTask don't return correct Result 3 answers

in this below code i want to return value from AsyncTask with using an Interface. but i get wrong value and i can not return correct value from onPostExecute.

i'm developed this link tutorials with my code. i can not use correctly with that.

Interface:

public interface AsyncResponse {
    void processFinish(String output);
}

Ksoap Main class:

public class WSDLHelper  implements AsyncResponse{
    public SoapObject request;

    private String Mainresult;

    public String call(SoapObject rq){

        ProcessTask p =new ProcessTask(rq);
        String tmp = String.valueOf(p.execute());

        p.delegate = this;

        return Mainresult;
    }


    @Override
    public void processFinish(String output) {

        this.Mainresult = output;
    }
}
class ProcessTask extends AsyncTask<Void, Void, Void > {
    public AsyncResponse delegate=null;

    SoapObject req1;
    private String result;
    public ProcessTask(SoapObject rq) {
        req1 = rq;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(Void... params) {

        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.setOutputSoapObject(this.req1);

        AndroidHttpTransport transport = new AndroidHttpTransport(Strings.URL_TSMS);
        transport.debug = true;

        try {
            transport.call(Strings.URL_TSMS + this.req1.getName(), envelope);
            this.result = envelope.getResponse().toString();
        } catch (IOException ex) {
            Log.e("" , ex.getMessage());
        } catch (XmlPullParserException ex) {
            Log.e("" , ex.getMessage());
        }

        if (result.equals(String.valueOf(Integers.CODE_USER_PASS_FALSE))) {
            try {
                throw new TException(PublicErrorList.USERNAME_PASSWORD_ERROR);
            } catch (TException e) {
                e.printStackTrace();
            }

        }

        Log.e("------------++++++++++++++++-----------", this.result);

        return null;
    }

    protected void onPostExecute(String result) {
    /* super.onPostExecute(result);*/
        delegate.processFinish(this.result);
    }

}

please help me to resolve this problem

回答1:

That can't work. You are creating and executing the AsyncTask (asynchronously!) and then call return Mainresult (synchronously!) when it hasn't received the result yet. The solution is to remove the redundant class WSDLHelper and access ProcessTask directly

Beside that, you're using AsyncTask incorrectly (saving the result in a class variable instead of passing it as a parameter). Here's the full version:

public class ProcessTask extends AsyncTask<Void, Void, String> {
public AsyncResponse delegate=null;

SoapObject req1;

public ProcessTask(SoapObject rq, AsyncResponse delegate) {
    req1 = rq;
    this.delegate = delegate;
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
}

@Override
protected Void doInBackground(Void... params) {

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    envelope.setOutputSoapObject(this.req1);

    AndroidHttpTransport transport = new AndroidHttpTransport(Strings.URL_TSMS);
    transport.debug = true;

    String result = null;
    try {
        transport.call(Strings.URL_TSMS + this.req1.getName(), envelope);
        result = envelope.getResponse().toString();
    } catch (IOException ex) {
        Log.e("" , ex.getMessage());
    } catch (XmlPullParserException ex) {
        Log.e("" , ex.getMessage());
    }

    if (result != null && result.equals(String.valueOf(Integers.CODE_USER_PASS_FALSE))) {
        try {
            throw new TException(PublicErrorList.USERNAME_PASSWORD_ERROR);
        } catch (TException e) {
            e.printStackTrace();
        }

    }

    Log.e("------------++++++++++++++++-----------", result);

    return result;
}

protected void onPostExecute(String result) {
/* super.onPostExecute(result);*/
    delegate.processFinish(result);
}

}

Now you would execute ProcessTask from outside like this, which will make sure you receive the result asynchronously:

new ProcessTask(rq, new AsyncResponse() {
    @Override
    public void processFinish(String output) {
        // do whatever you want with the result
    }
}).execute();


回答2:

Your result will always be null, because you return null in the doInBackground() method. The value you return in doInBackground() will be passed to onPostExecute(). Change your AsyncTask<Void, Void, Void> to AsyncTask<Void, Void, String>, and return the result. This will call onPostExecute(String result) with the correct result.

Perhaps this link might help you a bit: http://bon-app-etit.blogspot.be/2012/12/using-asynctask.html