移动开发中的通信架构(三)

前面两篇文章讲述了框架的大体情况和请求的封装,这篇文章讲述请求的发送。在本框架中,请求生成以后,并不是马上发送,而是加入一个请求列表。然后有一个线程来维护这个请求列表。

下面来具体分析,从移动开发中的通信架构(二)的第一段代码中取出:

sendRequest(request);

sendRequest方法由HttpHandler类提供,下面是HttpHandler的源代码:

package app.http; import java.util.Vector; /** * *在调用sendRequest方法的时候,其实并没有发生真正的网络请求,仅仅是把Request对象加入到了请求列表vctRequests中 * *在以后的设计中,注意vctRequests要保持线程安全的特性,因为UI和网络线程都会不停的调用它 * */ /** * 功能: * * 联系 整个程序的控制类 和 真正的网络类,其实也就是网络模块中的控制类 * * 维护一个列表,从程序中接受Request,然后把Request转发给HttpClient */ public class HttpHandler implements Timeable, Runnable { private boolean isRunning = false; // Http client private HttpClient httpClient = null; // 超时时间 private int timeout; // 重新连接次数 private int retries; // HttpListener private HttpListener httpListener = null; // Http监视器 private HttpMonitor monitor = null; // 等待发送的缓冲请求信息 private Vector vctRequests = new Vector(); private int state = STATE_REST; private final static int STATE_REST = 0; private final static int STATE_CANCEL = 1; private final static int STATE_ACTIVE = 2; public HttpHandler(HttpListener httpListener, int _msgId) { this(HttpConstants.DEFAULT_OVERTIME, HttpConstants.DEFAULT_RETRIES, httpListener, _msgId); } public HttpHandler(int timeout, int retries, HttpListener httpListener, int _msgId) { this.retries = retries; this.timeout = timeout; this.httpListener = httpListener; this.isRunning = true; httpClient = new HttpClient(_msgId); Thread t = new Thread(this); t.start(); } /** * 设置监听器 (多用于屏幕切换后更改监听器用) * * @param httpListener */ public void setHttpListener(HttpListener httpListener) { this.httpListener = httpListener; } public void run() { while (isRunning) { try { if (vctRequests.size() > 0) { Request request = null; synchronized (vctRequests) { if (vctRequests.size() > 0) { request = (Request) vctRequests.elementAt(0); vctRequests.removeElementAt(0); } } Response resp = getResponse(request); // 数据到达 if (resp != null) { if (httpListener != null) { httpListener.completed(resp); } resp = null; } } Thread.sleep(200); } catch (Exception ex) { } } } private void handleException(Exception ex) { if (httpListener != null && state == STATE_ACTIVE) { try { httpListener.exception(ex, this); } catch (Exception e) { e.printStackTrace(); } } } /** * Provides an interrupt to the initiated request. This method is typically */ public void timeout() { // 数据接收超时 cleanup(); handleException(new Exception("网络连接超时...")); } /** * 发送Request * * @param request */ public void sendRequest(Request request) { if (request == null) { return; } synchronized (vctRequests) { vctRequests.addElement(request); } } /** * 接收数据 * * @return */ public Response getResponse(Request request) { Response resp = null; int thisTry = 1; while (thisTry <= retries) { try { startTimer(); state = STATE_ACTIVE; httpListener.netSatus("正在进行网络连接..."); /** * 核心语句 */ resp = httpClient.getResponse(request); stopTimer(); state = STATE_REST; break; } catch (Exception e) { e.printStackTrace(); stopTimer(); if (state == STATE_CANCEL) { state = STATE_REST; break; } else if (thisTry >= retries) { cleanup(); handleException(new Exception("网络连接失败...")); } state = STATE_REST; } finally { thisTry++; } } return resp; } /** * 关闭连接,释放相关资源 */ private void cleanup() { try { // 关闭监视器 this.cancelTimer(); monitor = null; // 回收http资源 httpClient.cleanup(); } catch (Exception e) { e.printStackTrace(); } } /** * 获取当前发送信息的条数 * * @return int */ public int getVctRequests() { synchronized (vctRequests) { return vctRequests.size(); } } /** * 中断线程 */ public void stop() { // 请空缓存请求数据 synchronized (vctRequests) { vctRequests.removeAllElements(); } httpListener = null; cleanup(); // 中断数据接收监听 isRunning = false; httpClient = null; } public void cancelAccess() { if (state == STATE_ACTIVE) { state = STATE_CANCEL; cleanup(); } } public void startTimer() { if (timeout > 0) { monitor = getRequestTimer(); monitor.startTimer(); } } private HttpMonitor getRequestTimer() { if (monitor == null) { monitor = new HttpMonitor(this, timeout); monitor.start(); } return monitor; } /** * Issues a stopTimer() call to the <code>SocketMonitor</code>. * * @see java.io.InputStream */ public void stopTimer() { if (timeout > 0 && monitor != null) { monitor.stopTimer(); } } /** * Issues a cancelTimer() call to the <code>SocketMonitor</code>. */ public void cancelTimer() { if (timeout > 0) { if (monitor != null) { monitor.cancelTimer(); } } } public void pauseTimer() { if (monitor != null) { monitor.pauseMonitor(); } } public void resumeTimer() { if (monitor != null) { monitor.resumeMonitor(); } } }


请读者自行关注里面的重要方法,本人只是罗列一下:

public void run();

public void sendRequest(Request request);

public Response getResponse(Request request);

从程序代码中可以看到,HttpHandler是整个通信框架的耦合点:

1.它借助于下一篇讲述的Httpclient来实现请求的发送。

2.它借助于Timeable和HttpMonitor实现超时的控制。

3.它借助于HttpListener完成和UI线程的沟通。

下面罗列Timeable和HttpMonitor的源代码,超时的控制比较简单,我就不详细讲述。

package app.http; /** * 计时器辅助接口 */ public interface Timeable { public void timeout(); public void startTimer(); public void stopTimer(); public void cancelTimer(); }


package app.http; /** *计时器类,主要用于监控http连接是否超时 */ public class HttpMonitor extends Thread { // 超时时间(毫秒) private long timeout; private Timeable timeable; private long startTime; private boolean active = false; private boolean timing = false; private boolean bPaused = false; public HttpMonitor(Timeable t, int timeout) { this.timeout = timeout * 1000; timeable = t; timing = false; } public void pauseMonitor() { bPaused = true; } public void resumeMonitor() { startTime = System.currentTimeMillis(); bPaused = false; } public void run() { active = true; while (active) { if (timing) { long tmp = System.currentTimeMillis() - startTime; if (!bPaused && (tmp) > timeout) { timeable.timeout(); stopTimer(); } else { try { sleep(HttpConstants.MONITOR_INTERVAL); } catch (InterruptedException ie) { active = false; } } } else { try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); active = false; } } } } public void startTimer() { if (!timing) { startTime = System.currentTimeMillis(); timing = true; } } public void setTimeout() { try { stopTimer(); timeable.timeout(); } catch (Exception ex) { } } public void stopTimer() { timing = false; } public void cancelTimer() { active = false; timing = false; synchronized (this) { notifyAll(); } } public long getTimeout() { return timeout / 1000; } }


ps:有任何疑问可以留言,回复可能不及时,但是有意义的疑问一定回复。

ps:记得看到好文章好顶……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值