【问题标题】:Android AsyncTask don't return correct ResultAndroid AsyncTask 不返回正确的结果
【发布时间】:2014-11-03 16:16:51
【问题描述】:

对于我想使用KsoapAsyncTask 的项目之一。现在在下面的代码中AsyncTask 可以正常工作,但是在将结果返回到WSDLHeper 后,我得到了错误的值。例如doInBackground 方法中this.result 的结果是:

[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());

那是错的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);
    }

}

【问题讨论】:

  • 如果您想获得正确的 tmp 值,请尝试在 onPostExecute() 方法中获取该值。

标签: android android-asynctask android-ksoap2


【解决方案1】:

你无法获取AsyncTask的返回值

tmp = String.valueOf(p.execute());

这是因为 Android 应用不会等待 AsyncTask 返回值来移动到下一行。

你需要使用onPostExecute()方法来处理AsyncTask的返回值。

您可以参考AsyncTask: where does the return value of doInBackground() go? 了解更多语法和更多信息。

【讨论】:

  • onPostExecute() 默认为void,我不能使用return this.result。请帮我把它的价值返回给WSDLHelper谢谢。你的介绍链接onPostExecute()不返回任何值
  • Protected void onPostExecute(Long result) { showDialog("Downloaded " + result + " bytes");我理解你担心这不会返回任何东西。但是你得到 doInBackground() 的返回值作为 onPostExecute() 的参数。例如,如果您需要从 doInBackground() 方法返回 String,则使用 onPostExecute(String)
【解决方案2】:

你根本不能从 asyncTask 中返回值,你可以解析结果,在doInbackground()onPostExecute() 中做任何你想做的事情,如果你想要更多的灵活性,你可以调用一个存在于 asyncTask 之外的方法从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);
    }
:
:

你真的需要阅读 JTsunami 发布的链接

【讨论】:

    【解决方案3】:

    这个问题似乎源于 Mahdi 对 the answer here 的困惑,而 the answer here 以前建议使用

    ProcessTask p = new ProcessTask(...);
    String result = p.execute();
    

    这显然不能像 JTsunami 解释的那样工作。无论如何,由于这种混淆,Mahdi 的意图是创建和执行 AsyncTask(异步!),然后在尚未收到结果时返回 AsyncTask 的结果(同步!)。唯一的解决方案是在 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
        }
    });
    

    这将确保您异步接收结果,但仍然在调用该方法的同一个类中。注意 call(...) 的返回类型是 void:你必须在 onResult() 中处理结果

    【讨论】:

      猜你喜欢
      • 2012-04-11
      • 2016-02-06
      • 2017-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多