Android AsyncTask不会返回正确的结果

时间:2014-09-10 05:56:14

标签: android android-asynctask android-ksoap2

我希望KsoapAsyncTask一起使用的项目之一。现在在下面的代码中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);
    }

}

3 个答案:

答案 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()中处理结果。