我希望Ksoap
与AsyncTask
一起使用的项目之一。现在在下面的代码中AsyncTask
可以正常工作,但在将结果返回到WSDLHeper
后,我得到了wronge值。例如this.result
方法中doInBackground
的结果是:
[1, 4674070, {item=3000738; item=TSMS; item=30007227; item=30004444440000; item=30007227001401; item=50004066569100; item=50001717; item=500017171; item=5000171717; item=50001717007227; }]
返回值之后我在tmp = String.valueOf(p.execute())
中有:
ir.tsms.wsdl.ProcessTask@417b65e0
在这一行:
tmp = String.valueOf(p.execute());
那个wronge tmp
必须有
[1, 4674070, {item=3000738; item=TSMS; item=30007227; item=30004444440000; item=30007227001401; item=50004066569100; item=50001717; item=500017171; item=5000171717; item=50001717007227; }]
返回。
我的代码:
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);
}
}
答案 0 :(得分:4)
您无法通过
获取AsyncTask的返回值 tmp = String.valueOf(p.execute());
这是因为Android应用程序不会等待AsyncTask返回值以移动到下一行。
您需要使用onPostExecute()
方法来处理AsyncTask的返回值。
您可以参考AsyncTask: where does the return value of doInBackground() go?以获取更多语法和更多信息。
答案 1 :(得分:2)
你根本无法从asyncTask返回值,你可以解析结果,在doInbackground()
或onPostExecute()
内做你想做的事情,如果你想要更多的灵活性,你可以调用一个方法存在传递来自onPostexecute()
的结果的asyncTask:
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);
}
:
:
你真的需要阅读JTsunami发布的链接
答案 2 :(得分:1)
似乎这个问题源于马赫迪与the answer here的混淆,后者建议使用
ProcessTask p = new ProcessTask(...);
String result = p.execute();
这显然不能像JTsunami在这里解释的那样工作。无论如何,由于这种混乱,Mahdi的意图是创建并执行AsyncTask(异步!),然后在尚未收到结果时返回AsyncTask(同步!)的结果。唯一的解决方案是处理结果INSIDE onPostExecute()。如果需要将结果传递给其他对象(如Activity或Fragment),则必须主动传递结果,因为execute()和call(...)永远不会等待它。一个好的选择是通过替换
来注册一个监听器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);
}
}
与
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);
}
现在你打电话给
WSDLHelper.call(-your SoapObject here-, new ResultListener() {
@Override
public void onResult(String result) {
// do whatever you want with the result
}
});
这将确保您异步接收结果,但仍然在调用方法的同一个类中。请注意,返回类型的调用(...)是无效的:您必须在onResult()中处理结果。