问题
for one of projects i want to use Ksoap
with AsyncTask
. now in this below code AsyncTask
can work correctly but after return result to WSDLHeper
i get wronge value. for example Result for this.result
in doInBackground
method is :
[1, 4674070, {item=3000738; item=TSMS; item=30007227; item=30004444440000; item=30007227001401; item=50004066569100; item=50001717; item=500017171; item=5000171717; item=50001717007227; }]
after return value i'm in tmp = String.valueOf(p.execute())
have :
ir.tsms.wsdl.ProcessTask@417b65e0
in this line:
tmp = String.valueOf(p.execute());
and thats wronge tmp
must be have
[1, 4674070, {item=3000738; item=TSMS; item=30007227; item=30004444440000; item=30007227001401; item=50004066569100; item=50001717; item=500017171; item=5000171717; item=50001717007227; }]
to return.
My code:
public class WSDLHelper {
public SoapObject request;
public static String call(SoapObject rq){
String tmp;
ProcessTask p =new ProcessTask(rq);
tmp = String.valueOf(p.execute());
return tmp;
}
}
class ProcessTask extends AsyncTask<Void, Void, String > {
SoapObject req1;
private String result;
public ProcessTask(SoapObject rq) {
req1 = rq;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String 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();
}
return null;
}
return this.result;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
回答1:
You cannot get the return value of AsyncTask by
tmp = String.valueOf(p.execute());
This is because Android app doesn't wait for AsyncTask to return a value to move to next line.
You need to use the onPostExecute()
Method to process the return value of an AsyncTask .
You can refer AsyncTask: where does the return value of doInBackground() go? for more syntax and more information.
回答2:
you can't return value from asyncTask at all, you can parse result, do what ever you want inside doInbackground()
or in onPostExecute()
, if you want more flexibility, you can call a method exist out of the asyncTask passing the result from onPostexecute()
:
private void continueWithResult(String data){
//do whatever you want with the json passed from onPostExecute()
}
class ProcessTask extends AsyncTask<Void, Void, String > {
:
:
@Override
protected void onPostExecute(String result) {
continueWithResult(result);
}
:
:
and you really need to read the link posted by JTsunami
回答3:
It seems this question spawned from Mahdi's confusion with the answer here, which formerly suggested using
ProcessTask p = new ProcessTask(...);
String result = p.execute();
This obviously can't work as explained by JTsunami here. Anyway, because of that confusion, the intention of Mahdi here is to create and execute the AsyncTask (asynchronously!) and then return the result of the AsyncTask (synchronously!) when it hasn't received the result yet. The only solution is to handle the result INSIDE onPostExecute(). If you need to pass the result to other objects, like an Activity or Fragment, you have to actively pass the result because execute() and call(...) will never wait for it. A good option is to register a listener by replacing
public static String call(SoapObject request) {
ProcessTask p =new ProcessTask(request);
return p.execute();
}
class ProcessTask extends AsyncTask<Void, Void, SoapObject>
SoapObject request;
public String ProcessTask(SoapObject rq) {
request = rq;
}
...
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
with
public void String call(SoapObject request, ResultListener listener) {
ProcessTask p = new ProcessTask(request, listener);
p.execute();
}
class ProcessTask extends AsyncTask<Void, Void, SoapObject>
private SoapObject request;
private ResultListener listener;
public String ProcessTask(SoapObject rq, ResultListener l) {
request = rq;
listener = l;
}
...
@Override
protected void onPostExecute(String result) {
listener.onResult(result);
}
}
public interface ResultListener {
void onResult(String result);
}
Now you would call
WSDLHelper.call(-your SoapObject here-, new ResultListener() {
@Override
public void onResult(String result) {
// do whatever you want with the result
}
});
which will make sure you receive the result asynchronously, but still in the same class that calls the method. Note that the return type of call(...) is void: You have to handle the result inside onResult().
来源:https://stackoverflow.com/questions/25758236/android-asynctask-dont-return-correct-result