【问题标题】:Android return value in AsyncTask onPostExecute using Interface [duplicate]Android在AsyncTask onPostExecute中使用接口返回值[重复]
【发布时间】:2014-09-10 07:17:55
【问题描述】:

在下面的代码中,我想使用接口从AsyncTask 返回值。但我得到了错误的值,我无法从onPostExecute 返回正确的值。

我用我的代码开发了这个link 教程。我不能正确使用它。

界面:

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

Ksoap主类:

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);
    }

}

请帮我解决这个问题

【问题讨论】:

  • 更改doInBackground()onPostExecute()的返回类型,然后使用return语句返回你的对象

标签: java android android-asynctask android-ksoap2


【解决方案1】:

那是行不通的。您正在创建和执行 AsyncTask(异步!),然后在尚未收到结果时调用 return Mainresult(同步!)。解决方法是去掉多余的类WSDLHelper,直接访问ProcessTask

除此之外,您错误地使用了 AsyncTask(将结果保存在类变量中,而不是将其作为参数传递)。这是完整版:

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);
}

}

现在您可以像这样从外部执行 ProcessTask,这将确保您异步接收结果

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

【讨论】:

  • 谢谢先生。我如何在WSDLHelper 中开发call 方法?我在ProcessTask p =new ProcessTask(rq); 中的Contsructor 中出现错误,我将其更改为public String call(SoapObject rq){ ProcessTask p =new ProcessTask(rq,this); /*String tmp = String.valueOf(p.execute()); p.delegate = this;*/ return MainResult; } 但那不正确。
  • 哦,实际上,我还没有看到你的“p.delegate = this”。这在很多方面都是错误的……你还没有理解接口的概念。您正在执行 AsyncTask 并期望立即返回其结果。它是异步的,所以这是不可能的!我会更新我的答案。
  • 对不起,先生。我正在开发您将代码更新为 paste.debian.net/120158 。但那是错误的并返回NullPointerException
  • 删除 WSDLHelper。 不要返回“Mainresult”,它是空的,因为 ProcessTask 异步返回它的结果! 在 processFinish() 中处理结果。如果你不能理解这一点,你必须阅读Processes and Threads——否则没有人可以帮助你。
  • 对不起。我在您发送主题之前阅读了该链接,但我在所有项目中使用call 方法形式WSDLHelper,我必须从它返回结果才能使用其他方法,我不能删除 @ 987654333@。我可以在使用processFinish 获得输出后从它返回结果吗?例如:LoginFields loginSoapParser = tsms.SoapParser(wsdlHelper.call(tsms.SoapObjectRequest)); 请帮助我,谢谢
【解决方案2】:

您的结果将始终为 null,因为您在 doInBackground() 方法中返回 null。您在doInBackground() 中返回的值将传递给 onPostExecute()。将您的AsyncTask&lt;Void, Void, Void&gt; 更改为AsyncTask&lt;Void, Void, String&gt;,并返回结果。这将以正确的结果调用onPostExecute(String result)

也许这个链接可能会对你有所帮助:http://bon-app-etit.blogspot.be/2012/12/using-asynctask.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-19
    • 1970-01-01
    • 2012-03-16
    • 1970-01-01
    相关资源
    最近更新 更多