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

来源:互联网 发布:程序员喜欢的女生类型 编辑:程序博客网 时间:2024/05/20 00:15

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

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

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 clientprivate HttpClient httpClient = null;// 超时时间private int timeout;// 重新连接次数private int retries;// HttpListenerprivate 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:记得看到好文章好顶……

原创粉丝点击