从零开发一个完整的Android项目(二)——HTTP通信

HTTP通信

接上篇。项目主要使用HTTP协议与设备通信,所以最先说说。

代码

先上代码,又臭又长。后面有说明。
HttpConnection.java

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

/**
 * Created by song on 2017/5/28.
 */

/**
 * HTTP通信类
 * if in Chinese
 * URLEncoder.encode("xxxx","utf-8");
 * URLDecoder.decode("xxxx","utf-8");
 */
public class HttpConnection extends Thread {
    private boolean mRunning = true;
    private boolean mConnected = false;

    private HttpConnection() {

    }

    // 单实例
    private static final Object mSyncObject = new Object();
    private static HttpConnection mInstance;

    public static HttpConnection getInstance() {
        synchronized (mSyncObject) {
            if (mInstance != null) {
                return mInstance;
            }
            mInstance = new HttpConnection();
        }
        return mInstance;
    }

    // 传递数据给界面
    private Handler mHandler = null;

    public void setHandler(Handler handler) {
        this.mHandler = handler;
    }

    // Cookie
    private String mCookie = "";

    public String getCookie() {
        return mCookie;
    }

    // 请求队列
    private Queue<Request> queueRequest = new LinkedList<>();

    public void Add(int type, int id) {
        Add(type, id, "");
    }

    public void Add(int type, int id, String addition) {
        Add(type, id, addition, "");
    }

    public void Add(int type, int id, String addition, String data) {
        Request request = new Request(type, id, Defines.URLS[id] + addition, data);
        queueRequest.offer(request);
    }

    // GET请求
    private Response executeHttpGet(URL url) {
        if (url == null) {
            return null;
        }
        int responseCode = 0;
        String header = "";
        String result = "";
        HttpURLConnection connection = null;
        try {
            // 发送HTTP GET请求
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");                     // 设置请求的方式
            connection.setReadTimeout(5000);                        // 设置超时的时间
            connection.setConnectTimeout(5000);                     // 设置链接超时的时间
            if (!mCookie.equals("")) {
                connection.setRequestProperty("Cookie", mCookie);
            }
            connection.connect();

            // 接收HTTP GET响应
            Map<String, List<String>> responseHeaderMap = connection.getHeaderFields();
            int size = responseHeaderMap.size();
            Map<String, Object> headerMap = new HashMap<>();
            for (int i = 0; i < size; i++) {
                String responseHeaderKey = connection.getHeaderFieldKey(i);
                String responseHeaderValue = connection.getHeaderField(i);
                if (responseHeaderKey != null && responseHeaderValue != null) {
                    headerMap.put(responseHeaderKey, responseHeaderValue);
                }
            }
            header = JSONGenerator.GenJSON(headerMap).toString();

            responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                String strCookie = connection.getHeaderField("Set-Cookie");
                if (strCookie != null) {
                    mCookie = strCookie;
                    mConnected = true;
                }

                InputStream inputStream = connection.getInputStream();
                int len;
                byte[] bytes = new byte[1024];
                while ((len = inputStream.read(bytes)) > 0) {
                    result += new String(bytes, 0, len, "ISO-8859-1");
                }
                inputStream.close();
//			in = new InputStreamReader(connection.getInputStream());
//			BufferedReader bufferedReader = new BufferedReader(in);
//			int len = 0;
//			char [] buffer = new char[1024];
//			while((len = bufferedReader.read(buffer)) > 0){
//				result += new String(buffer, 0, len);
//			}

//			StringBuffer strBuffer = new StringBuffer();
//			String line;
//			while ((line = bufferedReader.readLine()) != null) {
//				strBuffer.append(line);
//			}
//			result = strBuffer.toString();
            } else if (responseCode == HttpURLConnection.HTTP_ACCEPTED
                    || responseCode == HttpURLConnection.HTTP_PARTIAL) {
                InputStream inputStream = connection.getInputStream();
                int len;
                byte[] bytes = new byte[1024];
                while ((len = inputStream.read(bytes)) > 0) {
                    result += new String(bytes, 0, len, "ISO-8859-1");
                }
                inputStream.close();
            } else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
                result = "error";
                mConnected = false;
            } else {
                result = String.valueOf(responseCode);
            }
        } catch (Exception e) {
            result = "error";
            mConnected = false;
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
        return new Response(responseCode, header, result);
    }

    // POST请求
    private Response executeHttpPost(URL url, String body) {
        if (url == null) {
            return null;
        }
        int responseCode = 0;
        String header = "";
        String result = null;
        HttpURLConnection connection = null;
        InputStreamReader in = null;
        try {
            // 发送HTTP POST请求
            connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Cookie", mCookie);
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.setRequestProperty("Charset", "utf-8");
            if (!body.equals("")) {
                DataOutputStream dop = new DataOutputStream(connection.getOutputStream());
                dop.writeBytes(body);
                dop.flush();
                dop.close();
            }
            connection.connect();

            // 接收HTTP POST响应
            responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                in = new InputStreamReader(connection.getInputStream());
                BufferedReader bufferedReader = new BufferedReader(in);
                StringBuffer strBuffer = new StringBuffer();
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    strBuffer.append(line);
                }
                result = strBuffer.toString();
            } else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
                result = "error";
                mConnected = false;
            }
        } catch (Exception e) {
            result = "error";
            mConnected = false;
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return new Response(responseCode, header, result);
    }

    // DELETE请求
    private Response executeHttpDelete(URL url) {
        if (url == null) {
            return null;
        }
        int responseCode = 0;
        String header = "";
        String result = null;
        HttpURLConnection connection = null;
        try {
            // 发送HTTP DELETE请求
            connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setRequestMethod("DELETE");
            connection.setRequestProperty("Cookie", mCookie);
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.setRequestProperty("Charset", "utf-8");
            connection.connect();

            // 接收HTTP DELETE响应
            responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                result = "success";
            } else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
                result = "error";
                mConnected = false;
            }
        } catch (Exception e) {
            result = "error";
            mConnected = false;
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
        return new Response(responseCode, header, result);
    }

    // 发送心跳和处理请求线程
    @Override
    public void run() {
        mCookie = "";
        mRunning = true;
        while (mRunning) {
            try {
                Request request;
                Response response = null;
                int interfaceID = -1;
                if (mConnected) {
                    interfaceID = Defines.INTERFACE_HEART;
                    URL url = new URL(Defines.URLS[interfaceID]);
                    response = executeHttpGet(url);
                }

                if ((request = queueRequest.poll()) != null) {
                    interfaceID = request.id;
                    URL url = new URL(request.toString());
                    if (mConnected) {
                        switch (request.type) {
                            case Defines.REQUEST_GET:
                                response = executeHttpGet(url);
                                break;

                            case Defines.REQUEST_POST:
                                response = executeHttpPost(url, request.data);
                                break;

                            case Defines.REQUEST_DELETE:
                                response = executeHttpDelete(url);
                                break;

                            default:
                                break;
                        }
                    } else if (request.id == Defines.INTERFACE_CONNECT) {
                        response = executeHttpGet(url);
                    }
                    sleep(1);
                } else if (mConnected) {
                    sleep(500);
                } else {
                    sleep(1000);
                    continue;
                }

                if (response != null) {
                    // 从消息池中取出一个message
                    Message msg = mHandler.obtainMessage();
                    if (response.toString().equals("error")) {
                        interfaceID = Defines.ERROR;
                    }
                    msg.what = interfaceID;

                    // Bundle是message中的数据
                    Bundle b = new Bundle();
                    b.putInt("Status", response.statusCode);
                    b.putString("Header", response.header);
                    b.putString("Body", response.data);
                    msg.setData(b);

                    // 传递数据
                    if (mHandler != null) {
                        mHandler.sendMessage(msg); // 向Handler发送消息,更新UI
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void close() {
        mRunning = false;
    }

    // HTTP Request
    private static class Request {
        public final int type;          // 请求的类型
        public final int id;            // 请求的ID
        public final String content;    // 请求的url
        public final String data;       // 请求的Body

        public Request(int type, int id, String content, String data) {
            this.type = type;
            this.id = id;
            this.content = content;
            this.data = data;
        }

        @Override
        public String toString() {
            return content;
        }
    }

    // HTTP Response类
    private static class Response {
        public final int statusCode;    // 返回的状态码
        public final String header;     // 返回的Header
        public final String data;       // 返回的Body

        public Response(int statusCode, String header, String data) {
            this.statusCode = statusCode;
            this.header = header;
            this.data = data;
        }

        @Override
        public String toString() {
            return data;
        }
    }
}

说明

  • 由于只需要建立一个HTTP连接,所以选择使用单实例;
  • setHandler用来将Activity创建的Handler,用来传递数据;
  • 由于需要发送心跳,所以开了个线程,创建了请求队列;
  • 接受GET请求返回的Body有多种方式,可以根据需要选择。上面的代码为了接受二进制数据,使用了ISO-8859-1编码,如果是文本,需要解码;
  • 代码中的"error"和Defines.ERROR用于判断连接异常;

补充

  • 代码是可以用的,但是由于测试的不是很多,所以难免存在Bug和不合理的地方;
  • Defines类是相关常量(请求类型、请求ID、请求的url等)的定义,参见这里
  • JSONGenerator是一个合成JSON字符串的类,参见这里
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值