在API 22中不推荐使用DefaultHttpClient。它如何在Android中构建新的基于网络的应用程序?

时间:2015-03-24 09:33:42

标签: android networking androidhttpclient

在开发新的Android应用程序时,我需要查找类HttpClient包org.apache.http的文档。我注意到在API 22中已经弃用了整个软件包,并建议this page建议使用HttpURLConnection。我了解到使用较少弃用的对象是一种好习惯,但这是为了彻底改变一切。

这是我用于执行网络连接和处理响应的最有用的代码。

public class Proxy {

private HttpClient client;
private BasicHttpParams params;


/**
 * This class encapsulates a generic response from the server. It store if response is success or not, if it is empty or not,
 * the possible code and message associate to response. Also can be stored a generic data passed from server in the response.
 */
public class ServerResult {
    //...
}

/**
 * This interface is an handler in the classes that perform the client-server communication.
 */
public interface RestRequest {

    /**
     * Callback method called when a server response should interact with elements into caller object.
     * @param result Entity that represents the response of the server.
     * @param requestCode An integer value returned to the interface to recognize which request is associated to result.
     * @param index If many request are done can be report index of i-TH request.
     */
    public void onProgress(ServerResult result, int requestCode, int index);

    /**
     * Callback method called when a server response should handled to caller object. This callback 
     * runs on UI thread. 
     * @param result Entity that represents the response of the server.
     * @param requestCode An integer value returned to the interface to recognize which request is associated to result.
     */
    public void onResult(ServerResult result, int requestCode);
}


/**
 * This function parse a json response from server in a valid assignable data content.
 */
private ServerResult deserializeResponse(String json, int type) {
    //...
}
/**
 * Perform generic POST request.
 * @param postData List of {@code (key,value)} pairs.
 * @param uri Url to send request.
 * @return Body of server's response.
 */
private String doPostRequest(List<NameValuePair> postData, String uri)
{
    HttpPost postRequest = new HttpPost(uri);
    try
    {
        //  append postData to request
        postRequest.setEntity(new UrlEncodedFormEntity(postData, HTTP.UTF_8));
        //  Execute HTTP Post Request
        return ProxyUtils.getResponseFromRequest(client.execute(postRequest));
    }
    catch (ClientProtocolException e)
    {
        e.printStackTrace();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
    return null;
}

/**
 * Perform generic GET request.
 * @param uri Url to send request.
 * @return Body of server's response.
 */
private String doGetRequest(String uri)
{
    HttpGet getRequest = new HttpGet(uri);
    getRequest.addHeader("Accept", "application/json");
    try
    {
        //  Execute HTTP Get Request
        return ProxyUtils.getResponseFromRequest(client.execute(getRequest));
    }
    catch (ClientProtocolException e)
    {
        e.printStackTrace();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }       
    return null;
}

/**
 * <p>The following object instantiate an async task thread where are performed web operations. Here can be execute only
 * execute GET and POST request.</p>
 * <p>Caller object must create it by constructor, giving appropriate parameters, then should call execute with a 
 * {@code List<NameValuePair>} arguments, that is entity of request. Also after thread execution this class give 
 * controller in the caller in {@code onPostExecute()} method, if is set callback object.</p>
 * @author Andrea Fabio
 */
public class RequestAsyncTask extends AsyncTask<List<NameValuePair>,Void,ServerResult> {

    private String uri;
    private int requestCode;
    private int methodType;
    /** Object that invoke rest request */
    private RestRequest sender;

    /**
     * Caller must call constructor to perform web operations.
     * @param uri The web URI in http:// format.
     * @param requestCode Code for parsing each particular response.
     * @param methodType Code between {@link GET_REQUEST} or {@link METHOD_POST}
     * @param sender Object to handle callback interface implemented by caller.
     */
    public RequestAsyncTask(String uri, int requestCode, int methodType, RestRequest sender) 
    {
        this.uri = uri;
        this.requestCode = requestCode;
        this.methodType = methodType;
        this.sender = sender;
    }

    @Override
    protected ServerResult doInBackground(List<NameValuePair>... data) 
    {
        client = new DefaultHttpClient(params);
        ServerResult result = null;
        switch(methodType)
        {
        case METHOD_GET:
            if(!data[0].isEmpty())
            {
                uri += "?";
                for(NameValuePair field : data[0])
                {
                    uri += field.getName()+"="+Uri.encode(field.getValue())+"&";
                }
                // remove last '&'
                uri = uri.substring(0, uri.length()-1);
            }
            Log.d(TAG, "Sending GET request("+requestCode+")\nUri: "+uri);
            result = deserializeResponse(doGetRequest(uri), requestCode);
            break;
        case METHOD_POST:
            Log.d(TAG, "Sending POST request("+requestCode+") \nUri: "+uri+" method, Entity: "+data[0].toString());
            result = deserializeResponse(doPostRequest(data[0], uri), requestCode);
            break;
        }
        client.getConnectionManager().closeIdleConnections(1, TimeUnit.SECONDS);
        if(this.sender!=null)
        {
            this.sender.onProgress(result, requestCode, 0);
        }
        return result;
    }

    @Override
    protected void onPostExecute(ServerResult result)
    {
        if(this.sender!=null)
        {
            this.sender.onResult(result, requestCode);
        }
    }

}
}

辅助类

public class ProxyUtils {

private static final String TAG = "ProxyUtils";
public static final int CODE_OK_HTTP = 200;

/**
 * To get content of entity from a Response provided by HttpClient connection.
 * @param response Result of connection from server.
 * @return If the header of a "200 OK" response contains the content of the response is decoded into a string 
 * otherwise {@code null }is returned if an error occurs between null response, header code> 400 or I / O errors
 */
public static String getResponseFromRequest(HttpResponse response)
{
    String result = null;
    if(response != null)
    {
        // server process request and sent a response
        if(response.getStatusLine().getStatusCode() == CODE_OK_HTTP)
        {
            // accept response
            StringBuilder resultBuilder = new StringBuilder();
            InputStream is;
            try
            {
                //  Get InputStream to the response text
                is = response.getEntity().getContent();
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(is));

                String line;
                // read all lines of response text
                while ((line = reader.readLine()) != null)
                {
                    resultBuilder.append(line);
                }
                is.close();
                // end request call
                result = resultBuilder.toString();

            }
            catch (IllegalStateException e)
            {
                e.printStackTrace();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
        else
        {
            // error response
            Log.d(TAG, "Response: "+response.getStatusLine().toString());
        }
    }
    else
    {
        // server didn't respond
        Log.d(TAG, "Server refused connection.");
    }
    return result;
}

}

我问网上最好的开发人员社区,因为你会更改代码以避免编写代码弃用。我还认为对代码的任何改进都对每个人都有帮助。

0 个答案:

没有答案