Android使用http协议与服务器通信

网上介绍Android上http通信的文章很多,不过大部分只给出了实现代码的片段,一些注意事项和如何设计一个合理的类用来处理所有的http请求以及返回结果,一般都不会提及。因此,自己对此做了些总结,给出了我的一个解决方案。

首先,需要明确一下http通信流程,Android目前提供两种http通信方式,HttpURLConnection和HttpClient,HttpURLConnection多用于发送或接收流式数据,因此比较适合上传/下载文件,HttpClient相对来讲更大更全能,但是速度相对也要慢一点。在此只介绍HttpClient的通信流程:

1.创建HttpClient对象,改对象可以用来多次发送不同的http请求

2.创建HttpPost或HttpGet对象,设置参数,每发送一次http请求,都需要这样一个对象

3.利用HttpClient的execute方法发送请求并等待结果,该方法会一直阻塞当前线程,直到返回结果或抛出异常。

4.针对结果和异常做相应处理

根据上述流程,发现在设计类的时候,有几点需要考虑到:

1.HttpClient对象可以重复使用,因此可以作为类的静态变量

2.HttpPost/HttpGet对象一般无法重复使用(如果你每次请求的参数都差不多,也可以重复使用),因此可以创建一个方法用来初始化,同时设置一些需要上传到服务器的资源

3.目前Android不再支持在UI线程中发起Http请求,实际上也不该这么做,因为这样会阻塞UI线程。因此还需要一个子线程,用来发起Http请求,即执行execute方法

4.不同的请求对应不同的返回结果,对于如何处理返回结果(一般来说都是解析json&更新UI),需要有一定的自由度。

5.最简单的方法是,每次需要发送http请求时,开一个子线程用于发送请求,子线程中接收到结果或抛出异常时,根据情况给UI线程发送message,最后在UI线程的handler的handleMessage方法中做结果解析和UI更新。这么写虽然简单,但是UI线程和Http请求的耦合度很高,而且代码比较散乱、丑陋。

基于上述几点原因,我设计了一个PostRequest类,用于满足我的http通信需求。我只用到了Post请求,如果你需要Get请求,也可以改写成GetRequest

package com.handspeaker.network;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.os.Handler;
import android.util.Log;

/**
 *
 * 用于封装&简化http通信
 *
 */
public class PostRequest implements Runnable {

    private static final int NO_SERVER_ERROR=1000;
    //服务器地址
    public static final String URL = "fill your own url";
    //一些请求类型
    public final static String ADD = "/add";
    public final static String UPDATE = "/update";
    public final static String PING = "/ping";
    //一些参数
    private static int connectionTimeout = 60000;
    private static int socketTimeout = 60000;
    //类静态变量
    private static HttpClient httpClient=new DefaultHttpClient();
    private static ExecutorService executorService=Executors.newCachedThreadPool();
    private static Handler handler = new Handler();
    //变量
    private String strResult;
    private HttpPost httpPost;
    private HttpResponse httpResponse;
    private OnReceiveDataListener onReceiveDataListener;
    private int statusCode;

    /**
     * 构造函数,初始化一些可以重复使用的变量
     */
    public PostRequest() {
        strResult = null;
        httpResponse = null;
        httpPost = new HttpPost();
    }

    /**
     * 注册接收数据监听器
     * @param listener
     */
    public void setOnReceiveDataListener(OnReceiveDataListener listener) {
        onReceiveDataListener = listener;
    }

    /**
     * 根据不同的请求类型来初始化httppost
     *
     * @param requestType
     *            请求类型
     * @param nameValuePairs
     *            需要传递的参数
     */
    public void iniRequest(String requestType, JSONObject jsonObject) {
        httpPost.addHeader("Content-Type", "text/json");
        httpPost.addHeader("charset", "UTF-8");

        httpPost.addHeader("Cache-Control", "no-cache");
        HttpParams httpParameters = httpPost.getParams();
        HttpConnectionParams.setConnectionTimeout(httpParameters,
                connectionTimeout);
        HttpConnectionParams.setSoTimeout(httpParameters, socketTimeout);
        httpPost.setParams(httpParameters);
        try {
            httpPost.setURI(new URI(URL + requestType));
            httpPost.setEntity(new StringEntity(jsonObject.toString(),
                    HTTP.UTF_8));
        } catch (URISyntaxException e1) {
            e1.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    /**
     * 新开一个线程发送http请求
     */
    public void execute() {
        executorService.execute(this);
    }

    /**
     * 检测网络状况
     *
     * @return true is available else false
     */
    public static boolean checkNetState(Activity activity) {
        ConnectivityManager connManager = (ConnectivityManager) activity
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connManager.getActiveNetworkInfo() != null) {
            return connManager.getActiveNetworkInfo().isAvailable();
        }
        return false;
    }

    /**
     * 发送http请求的具体执行代码
     */
    @Override
    public void run() {
        httpResponse = null;
        try {
            httpResponse = httpClient.execute(httpPost);
            strResult = EntityUtils.toString(httpResponse.getEntity());
        } catch (ClientProtocolException e1) {
            strResult = null;
            e1.printStackTrace();
        } catch (IOException e1) {
            strResult = null;
            e1.printStackTrace();
        } finally {
            if (httpResponse != null) {
                statusCode = httpResponse.getStatusLine().getStatusCode();
            }
            else
            {
                statusCode=NO_SERVER_ERROR;
            }
            if(onReceiveDataListener!=null)
            {
                //将注册的监听器的onReceiveData方法加入到消息队列中去执行
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        onReceiveDataListener.onReceiveData(strResult, statusCode);
                    }
                });
            }
        }
    }

    /**
     * 用于接收并处理http请求结果的监听器
     *
     */
    public interface OnReceiveDataListener {
        /**
         * the callback function for receiving the result data
         * from post request, and further processing will be done here
         * @param strResult the result in string style.
         * @param StatusCode the status of the post
         */
        public abstract void onReceiveData(String strResult,int StatusCode);
    }

}

代码使用了观察者模式,任何需要接收http请求结果的类,都要实现OnReceiveDataListener接口的抽象方法,同时PostRequest实例调用setOnReceiveDataListener方法,注册该监听器。完整调用步骤如下:

1.创建PostRequest对象,实现onReceiveData接口,编写自己的onReceiveData方法

2.注册监听器

3.调用PostRequest的iniRequest方法,初始化本次request

4.调用PostRequest的execute方法

可能的改进:

1.如果需要多个观察者,可以把只能注册单个监听器改为可以注册多个监听器,维护一个监听器List。

2.如果需求比较简单,并希望调用流程更简洁,iniRequest和execute可以合并

如果有更好的方法或者问题,欢迎随时交流

时间: 2024-10-02 16:22:39

Android使用http协议与服务器通信的相关文章

Android操作HTTP实现与服务器通信

本示例以Servlet为例,演示Android与Servlet的通信. 众所周知,Android与服务器通信通常采用HTTP通信方式和Socket通信方式,而HTTP通信方式又分get和post两种方式.至于Socket通信会在以后的博文中介绍. HTTP协议简介: HTTP (Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种协议. HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响

【Android笔记】Android操作HTTP实现与服务器通信

本示例以Servlet为例,演示Android与Servlet的通信. 众所周知,Android与服务器通信通常采用HTTP通信方式和Socket通信方式,而HTTP通信方式又分get和post两种方式.至于Socket通信会在以后的博文中介绍. HTTP协议简介: HTTP (Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种协议. HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响

Android操作HTTP实现和服务器通信

众所周知,Android与服务器通信通常采用HTTP通信方式和Socket通信方式,而HTTP通信方式又分get和post两种方式.至于Socket通信会在以后的博文中介绍. HTTP协议简介: HTTP (Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种协议. HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接.从建立连接到关闭连接的过程称为“一次连

基于Android硬件设备跟微信服务器通信的项目心得,以UDP Byte通信为例,建立无向连接,0530手札

这段时间挺忙的,微信企业号等微信系列的教程全部停滞了,原因是我手头上抓着几个项目,加班就不说了,今天刚刚把新接手的项目整到大概%80的样 子吧,准备明天整整,星期一过来直接对接测试,很多朋友跑过来问问题,我是真没时间,请见谅! 今天就分享下这个项目的总结,源码就不粘贴了,因为是商业项目,只是传达下编码思想,希望其他朋友在遇到类似项目的时候有个参考,不至于找不到 一点点思路 使用UDP进行通讯,每条指令不超过1024字节,所有多字节整形数据采用网络字节顺序传输.终端每上报一条指令,平台都将回复一条

HTTP基础与Android之(安卓与服务器通信)——使用HttpClient和HttpURLConnection

查看原文:http://blog.csdn.net/sinat_29912455/article/details/51122286 1客户端连接服务器实现内部的原理 GET方式和POST方式的差别 HTTP返回请求数据的三种方式 2使用HTTP协议访问网络 3HttpCient 简单来说用HttpClient发送请求接收响应都很简单只需要五大步骤即可要牢记 4DefaultHttpClient GET方式 POST方式 5Java中使用HTTPHttpURLConnection GET方式 PO

Android客户端通过socket与服务器通信

android端--Client package com.sec.chatroomandroid; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import android.ap

Android基础入门教程——7.6.4 基于UDP协议的Socket通信

Android基础入门教程--7.6.4 基于UDP协议的Socket通信 标签(空格分隔): Android基础入门教程 本节引言: 本节给大家带来Socket的最后一节:基于UDP协议的Socket通信,在第一节中我们已经详细地 比较了两者的区别,TCP和UDP最大的区别在于是否需要客户端与服务端建立连接后才能进行 数据传输,如果你学了前两节TCP的,传输前先开服务端,accept,等客户端接入,然后获得 客户端socket然后进行IO操作,而UDP则不用,UDP以数据报作为数据的传输载体,

Android基础入门教程——7.6.3 基于TCP协议的Socket通信(2)

Android基础入门教程--7.6.3 基于TCP协议的Socket通信(2) 标签(空格分隔): Android基础入门教程 本节引言: 上节中我们给大家接触了Socket的一些基本概念以及使用方法,然后写了一个小猪简易聊天室的 Demo,相信大家对Socket有了初步的掌握,本节我们来学习下使用Socket来实现大文件的断点续传! 这里讲解的是别人写好的一个Socket上传大文件的例子,不要求我们自己可以写出来,需要的时候会用 就好! 1.运行效果图: 1.先把我们编写好的Socket服务

Android基础入门教程——7.6.2 基于TCP协议的Socket通信(1)

Android基础入门教程--7.6.2 基于TCP协议的Socket通信(1) 标签(空格分隔): Android基础入门教程 本节引言: 上一节的概念课枯燥无味是吧,不过总有点收获是吧,本节开始我们来研究基于TCP协议的Socket 通信,先来了解下Socket的概念,以及Socket通信的模型,实现Socket的步骤,以及作为Socket服务 端与客户端的两位各做要做什么事情!好的,我们由浅入深来扣这个Socket吧! 1.什么是Socket? 2.Socket通信模型: Socket通信