我将尽可能简化这一过程。

我在控制层中有一个方法,该方法使用扩展CallServiceTask的类AsyncTask。调用新的CallServiceTask().execute(parameters)
如何检索从doInBackground返回的数据?我发现的所有教程都使用直接从AsyncTask扩展Activity的类。
我的问题要复杂得多。
我只想获取Object[]返回的doInBackground并将其设置为RestClient类的私有(private)数据成员。
CallServiceTask看起来像这样:

    private class CallServiceTask extends AsyncTask<Object, Void, Object[]>
{

    protected Object[] doInBackground(Object... params)
    {
        HttpUriRequest req = (HttpUriRequest) params[0];
        String url = (String) params[1];

        return executeRequest(req, url);
    }
}

我的RestClient类看起来像这样:
public class RestClient
{

private ArrayList <NameValuePair> params;
private ArrayList <NameValuePair> headers;

private JSONObject jsonData;

private Object[] rtnData;

private String url;

private boolean connError;

public int getResponseCode() {
    return responseCode;
}

/**
 *
 * @return  the result of whether the login was successful by looking at the response parameter of the JSON object.
 */
public Boolean DidLoginSucceed()
{
    // Will Crash on socket error
        return ((JSONObject) rtnData[0]).optBoolean("response");
}

public String GetToken()
{
    return jsonData.optString("token");
}

public RestClient(String url)
{
    this.url = url;
    params = new ArrayList<NameValuePair>();
    headers = new ArrayList<NameValuePair>();
    rtnData = new Object[]{ new JSONObject() , Boolean.TRUE  };
}

public void AddParam(String name, String value)
{
    params.add(new BasicNameValuePair(name, value));
}

public void AddHeader(String name, String value)
{
    headers.add(new BasicNameValuePair(name, value));
}

/**
 * This method will execute, call the service and instantiate the JSON Object through executeRequest().
 *
 * @param method    an enum defining which method you wish to execute.
 * @throws Exception
 */
public void ExecuteCall(RequestMethod method) throws Exception
{
    Object[] parameters = new Object[]{ new HttpGet() , new String("") };
    switch(method) {
        case GET:
        {
            //add parameters
            String combinedParams = "";
            if(!params.isEmpty()){
                combinedParams += "?";
                for(NameValuePair p : params)
                {
                    String paramString = p.getName() + "=" + URLEncoder.encode(p.getValue());
                    if(combinedParams.length() > 1)
                    {
                        combinedParams  +=  "&" + paramString;
                    }
                    else
                    {
                        combinedParams += paramString;
                    }
                }
            }

            HttpGet request = new HttpGet(url + combinedParams);

            //add headers
            for(NameValuePair h : headers)
            {
                request.addHeader(h.getName(), h.getValue());
            }
            parameters[0] = request;
            parameters[1] = url;

            new CallServiceTask().execute(parameters);

            jsonData = ((JSONObject) rtnData[0]).optJSONObject("data");
            connError = (Boolean) rtnData[1];
            break;

        }
        case POST:
        {
            HttpPost request = new HttpPost(url);

            //add headers
            for(NameValuePair h : headers)
            {
                request.addHeader(h.getName(), h.getValue());
            }

            if(!params.isEmpty()){
                request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
            }
            new CallServiceTask().execute(request, url);
            break;
        }
    }
}

private Object[] executeRequest(HttpUriRequest request, String url)
{
    HttpClient client = new DefaultHttpClient();
    client = getNewHttpClient();

    HttpResponse httpResponse;

    try {
        httpResponse = client.execute(request);
        HttpEntity entity = httpResponse.getEntity();

        if (entity != null) {

            InputStream instream = entity.getContent();
            String response = convertStreamToString(instream);
            try {
                rtnData[0] = new JSONObject(response);
                rtnData[1] = false;

            } catch (JSONException e1) {
                rtnData[1] = true;
                e1.printStackTrace();
            }

            // Closing the input stream will trigger connection release
            instream.close();
        }

    } catch (ClientProtocolException e)  {
        client.getConnectionManager().shutdown();
        e.printStackTrace();
    } catch (IOException e) {
        client.getConnectionManager().shutdown();
        e.printStackTrace();
    }
    return rtnData;
}


private static String convertStreamToString(InputStream is) {

    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();

    String line = null;
    try {
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return sb.toString();
}

/**
 * Custom HTTP Client accepting all SSL Certified Web Services.
 *
 * @return n HttpClient object.
 */
public HttpClient getNewHttpClient() {
    try {
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null, null);

        SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
        sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", sf, 443));

        ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

        return new DefaultHttpClient(ccm, params);
    } catch (Exception e) {
        return new DefaultHttpClient();
    }
}

最佳答案

唯一的方法是使用CallBack。您可以执行以下操作:

new CallServiceTask(this).execute(request, url);

然后在您的CallServiceTask中添加一个本地类变量,并在onPostExecute中从该类中调用一个方法:
private class CallServiceTask extends AsyncTask<Object, Void, Object[]>
{
    RestClient caller;

    CallServiceTask(RestClient caller) {
        this.caller = caller;
    }


    protected Object[] doInBackground(Object... params)
    {
        HttpUriRequest req = (HttpUriRequest) params[0];
        String url = (String) params[1];
        return executeRequest(req, url);
    }

    protected onPostExecute(Object result) {
        caller.onBackgroundTaskCompleted(result);
    }
}

然后,只需在RestClient类的onBackgroundTaskCompleted()方法中随意使用Object即可。

一个更优雅,更可扩展的解决方案是使用接口(interface)。有关示例实现,请参见this库。我刚刚启动它,但是它有您想要的示例。

10-08 14:14