




已阅读5页,还剩9页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
中文开发者社区 Android也架构之三:简单工厂模式优化网络请求很悲催,我们在Android也架构之二:单例模式访问网络 用httpConnect的方式去访问网络,而且能够正常获取数据了,可是老板能,技术出生,他要求我重新用httpClient去获取获取网络数据,童鞋们,是不是头快爆炸了?你是否也遇见过这样的或者类似这样的情况呢? 拥抱变化,让我们冲现在开始吧,上一篇文章Android也架构之二:单例模式访问网络中,我们学会用了单例模式,单例模式一般解决的是和程序相关的问题,和业务逻辑无关,今天开始,我们就开始学习和业务相关的设计模式,拥抱变化,让业务和需求的变化放马过来吧。今天,通过这篇文章,你讲学习到以下这些知识点:1、学会用简单工厂模式,基于api接口开发的工作模式,接口的特点是可插拔,不会影响到客户端数据。2、学会用httpclient框架请求http数据,涉及到android的httpclient框架的细节知识点,比如httpclient自动重连机制,连接自动释放等3、学会在子线程如何更新主线程的android基础知识首先我们来看一下项目的目录结构:刚才说了,基于接口开发应该是可插拔的,就是说无论服务端(http包下的类)是怎么变化,都不会影响到客户端(clientActivity)的使用,服务端添加或者修改功能的时候不能修改客户端(clientActivity)代码。我们首先来看下AndroidManifest.xml的代码,很简单html view plaincopy1 2 6 7 8 9 12 15 16 17 18 19 20 21 22 23 24 25 26 里面主要是添加了访问网络的权限html view plaincopy27 28 接下来我们来看下布局文件main.xml,也非常简单。就一个textview用来显示网络的http数据html view plaincopy29 30 34 35 41 42 接下来,我们先来给网络模块定义一个接口,这个接口主要是用来读取网络,很简单,就只有一个方法。java view plaincopy43 package com.yangfuhai.simplefactory.http; 44 /* 45 * title http模块接口定义 46 * description 描述 47 * company 探索者网络工作室() 48 * author michael Young (www.YangF) 49 * version 1.0 50 * created 2012-8-21 51 */ 52 public interface HttpApi 53 54 public String getUrlContext(String strUrl); 55 56 接下来有两个类,放别实现了这个接口,一个是HttpURLConnection来实现,一个是httpclient来实现的。代码如下:HttpUtils:java view plaincopy57 package com.yangfuhai.simplefactory.http; 58 59 import java.io.IOException; 60 import java.io.InputStream; 61 import java.io.InputStreamReader; 62 import java.io.Reader; 63 import java.io.UnsupportedEncodingException; 64 import .HttpURLConnection; 65 import .URL; 66 67 import android.util.Log; 68 69 /* 70 * title Http请求工具类 71 * description 请求http数据,单例模式 72 * company 探索者网络工作室() 73 * author michael Young (www.YangF) 74 * version 1.0 75 * created 2012-8-19 76 */ 77 public class HttpUtils implements HttpApi 78 private static final String DEBUG_TAG = HttpUtils; 79 private HttpUtils() /单例模式中,封闭创建实例接口 80 81 private static HttpUtils httpUtils = null; 82 83 /提供了一个可以访问到它自己的全局访问点 84 public static HttpUtils get() 85 if(httpUtils = null) 86 httpUtils = new HttpUtils(); 87 return httpUtils; 88 89 90 /* 91 * 获取某个url的内容 92 * param strUrl 93 * return 94 */ 95 Override 96 public String getUrlContext(String strUrl) 97 InputStream is = null; 98 int len = 500; 99 100 try 101 URL url = new URL(strUrl); 102 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 103 conn.setReadTimeout(10000 /* milliseconds */); 104 conn.setConnectTimeout(15000 /* milliseconds */); 105 conn.setRequestMethod(GET); 106 conn.setDoInput(true); 107 conn.connect(); 108 int response = conn.getResponseCode(); 109 Log.d(DEBUG_TAG, The response is: + response); 110 is = conn.getInputStream(); 111 112 /这里指获取了500(len=500)字节,如果想 113 /整个网页全部获取可以用conn.getContentLength()来代替len 114 String contentAsString = readInputStream(is, len); 115 return contentAsString; 116 117 catch (Exception e) 118 e.printStackTrace(); 119 finally 120 if (is != null) 121 try 122 is.close(); 123 catch (IOException e) 124 e.printStackTrace(); 125 126 127 128 return null; 129 130 131 /* 132 * 读取 InputStream 内容 133 * param stream 134 * param len 135 * return 136 * throws IOException 137 * throws UnsupportedEncodingException 138 */ 139 private String readInputStream(InputStream stream, int len) throws IOException, UnsupportedEncodingException 140 Reader reader = null; 141 reader = new InputStreamReader(stream, UTF-8); 142 char buffer = new charlen; 143 reader.read(buffer); 144 return new String(buffer); 145 146 147 HttpClientUtils.java 类:java view plaincopy148 package com.yangfuhai.simplefactory.http; 149 150 import java.io.IOException; 151 import java.io.UnsupportedEncodingException; 152 import .URLEncoder; 153 import java.util.regex.Matcher; 154 import java.util.regex.Pattern; 155 156 import .ssl.SSLHandshakeException; 157 158 import org.apache.http.HttpEntity; 159 import org.apache.http.HttpEntityEnclosingRequest; 160 import org.apache.http.HttpRequest; 161 import org.apache.http.HttpResponse; 162 import org.apache.http.NoHttpResponseException; 163 import org.apache.http.client.ClientProtocolException; 164 import org.apache.http.client.HttpClient; 165 import org.apache.http.client.HttpRequestRetryHandler; 166 import org.apache.http.client.ResponseHandler; 167 import org.apache.http.client.methods.HttpGet; 168 import org.apache.http.client.methods.HttpRequestBase; 169 import org.apache.http.impl.client.DefaultHttpClient; 170 import org.apache.http.params.CoreConnectionPNames; 171 import org.apache.http.params.CoreProtocolPNames; 172 import tocol.ExecutionContext; 173 import tocol.HttpContext; 174 import org.apache.http.util.EntityUtils; 175 176 import android.util.Log; 177 178 /* 179 * title HttpClient获得网络信息 180 * description 描述 181 * company 探索者网络工作室() 182 * author michael Young (www.YangF) 183 * version 1.0 184 * created 2012-8-21 185 */ 186 public class HttpClientUtils implements HttpApi 187 188 private static final String DEBUG_TAG = HttpClientUtils; 189 private static final String CHARSET_UTF8 = UTF-8; 190 191 private HttpClientUtils() / 单例模式中,封闭创建实例接口 192 193 private static HttpClientUtils httpClientUtils = null; 194 195 /* 196 * 提供了一个可以访问到它自己的全局访问点 197 * return 198 */ 199 public static HttpClientUtils get() 200 if (httpClientUtils = null) 201 httpClientUtils = new HttpClientUtils(); 202 return httpClientUtils; 203 204 205 206 207 Override 208 public String getUrlContext(String strUrl) 209 String responseStr = null;/ 发送请求,得到响应 210 DefaultHttpClient httpClient = null; 211 HttpGet httpGet = null; 212 try 213 strUrl = urlEncode(strUrl.trim(), CHARSET_UTF8); 214 httpClient = getDefaultHttpClient(null); 215 httpGet = new HttpGet(strUrl); 216 responseStr = httpClient.execute(httpGet, strResponseHandler); 217 catch (ClientProtocolException e) 218 Log.e(DEBUG_TAG, e.getMessage(); 219 catch (IOException e) 220 Log.e(DEBUG_TAG, e.getMessage(); 221 catch (Exception e) 222 Log.e(DEBUG_TAG, e.getMessage(); 223 finally 224 abortConnection(httpGet, httpClient); 225 226 return responseStr; 227 228 229 230 231 /* 232 * 转码http的网址,只对中文进行转码 233 * 234 * param str 235 * param charset 236 * return 237 * throws UnsupportedEncodingException 238 */ 239 private static String urlEncode(String str, String charset) 240 throws UnsupportedEncodingException 241 Pattern p = Ppile(u4e00-u9fa5+); 242 Matcher m = p.matcher(str); 243 StringBuffer b = new StringBuffer(); 244 while (m.find() 245 m.appendReplacement(b, URLEncoder.encode(m.group(0), charset); 246 247 m.appendTail(b); 248 return b.toString(); 249 250 251 252 253 /* 254 * 设置重连机制和异常自动恢复处理 255 */ 256 private static HttpRequestRetryHandler requestRetryHandler = new HttpRequestRetryHandler() 257 / 自定义的恢复策略 258 public boolean retryRequest(IOException exception, int executionCount, 259 HttpContext context) 260 / 设置恢复策略,在Http请求发生异常时候将自动重试3次 261 if (executionCount = 3) 262 / Do not retry if over max retry count 263 return false; 264 265 if (exception instanceof NoHttpResponseException) 266 / Retry if the server dropped connection on us 267 return true; 268 269 if (exception instanceof SSLHandshakeException) 270 / Do not retry on SSL handshake exception 271 return false; 272 273 HttpRequest request = (HttpRequest) context 274 .getAttribute(ExecutionContext.HTTP_REQUEST); 275 boolean idempotent = (request instanceof HttpEntityEnclosingRequest); 276 if (!idempotent) 277 / Retry if the request is considered idempotent 278 return true; 279 280 return false; 281 282 ; 283 284 285 / 使用ResponseHandler接口处理响应,HttpClient使用ResponseHandler会自动管理连接的释放, 286 /解决对连接的释放管理 287 private static ResponseHandler strResponseHandler = new ResponseHandler() 288 / 自定义响应处理 289 public String handleResponse(HttpResponse response) 290 throws ClientProtocolException, IOException 291 HttpEntity entity = response.getEntity(); 292 if (entity != null) 293 String charset = EntityUtils.getContentCharSet(entity) = null ? CHARSET_UTF8 294 : EntityUtils.getContentCharSet(entity); 295 return new String(EntityUtils.toByteArray(entity), charset); 296 else 297 return null; 298 299 300 ; 301 302 303 304 305 /* 306 * 获取DefaultHttpClient实例 307 * 308 * param charset 309 * return 310 */ 311 private static DefaultHttpClient getDefaultHttpClient(final String charset) 312 DefaultHttpClient httpclient = new DefaultHttpClient(); 313 / httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, 314 / HttpVersion.HTTP_1_1); 315 / 模拟浏览器(有些服务器只支持浏览器访问,这个可以模拟下) 316 / httpclient.getParams().setParameter(CoreProtocolPNames.USER_AGENT,Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1); 317 / httpclient.getParams().setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE,Boolean.FALSE); 318 319 / 请求超时 320 httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000); 321 / 读取超时 322 httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,5000); 323 httpclient.getParams().setParameter( 324 CoreProtocolPNames.HTTP_CONTENT_CHARSET, 325 charset = null ? CHARSET_UTF8 : charset); 326 httpclient.setHttpRequestRetryHandler(requestRetryHandler); 327 return httpclient; 328 329 330 /* 331 * 释放HttpClient连接 332 * 333 * param hrb 334 * param httpclient 335 */ 336 private static void abortConnection(final HttpRequestBase httpRequestBase, 337 final HttpClient httpclient) 338 if (httpRequestBase != null) 339 httpRequestBase.abort(); 340 341 if (httpclient != null) 342 httpclient.getConnectionManager().shutdown(); 343 344 345 346 接下来,我们过来看看工厂类:java view plaincopy347 package com.yangfuhai.simplefactory.http; 348 349 /* 350 * title Http模块工厂 351 * description 获取http模块 352 * company 探索者网络工作室() 353 * author michael Young (www.YangF) 354 * version 1.0 355 * created 2012-8-21 356 */ 357 public class HttpFactory 358 359 private static final int HTTP_CONFIG= 1 ;/http调用方式,0是httpConnect,1是httpclient 360 361 public static HttpApi getHttp() 362 if(HTTP_CONFIG = 0) 363 return HttpUtils.get(); 364 else if(HTTP_CONFIG = 1) 365 return HttpClientUtils.get(); 366 367 return null; 368 369 370 在工厂类中,一般获取http内部模块有几种模式,一种是由客户端传值进来获取某个指定的模块,一种是由HttpFactory内部逻辑实现,会更加需求或者其他一些特定的条件返回不同的接口,一种是通过配置文件获取,比如读取某个文件等。 这里我们简单的模拟了读取网络配置文件 获取的形式,我们可以通过HTTP_CONFIG 的配置返回不同的http模块,不论是httpUrlConnection的方式还是httpclient的形式,只要简单的在这里配置就行了,无论这里怎么修改都不会影响到客户端(httpclient)的代码,哪天老板心血来潮,弄一个icp/ip,socket的形式获取网络信息,我们只需要在这个包(com.yangfuhai.simplefactory.http)下添加一个socket获取网络信息的类,我们也不用修改客户端(clientActivity)的代码啦(鼓掌XXXXX),同时,我们可以移除httpUrlConnection或者httpClient的类,对客户端一点影响都没有(可插拔)。客户端代码如下:java view plaincopy371 package com.yangfuhai.simplefactory; 372 373 import com.yangfuhai.simplefactory.http.HttpFactory; 374 375 import android.app.Activity; 376 import android.os.Bundle; 377 import android.widget.TextVie
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 工程电梯销售合同范本
- 大型合同范本
- 房屋转卖装修合同范本
- 多人承包鱼塘合同范本
- 校外配餐机构合同范本
- 铲车司机雇佣 合同范本
- 购车定金电子合同范本
- 街区商业招商合同范本
- 特殊空调租赁合同范本
- 养老机构常用合同范本
- 厨房消防安全培训
- 小陈 税务风险应对常见指标与答复思路
- 2025年《中华人民共和国档案法》知识培训试题及答案
- 2026年高考政治一轮复习:必修2《经济与社会》知识点背诵提纲
- 2025至2030年中国建筑膜行业市场调查研究及发展趋势预测报告
- 2025年急诊急救试题(附答案)
- 变电站新员工培训课件
- 会所会议室管理制度
- 2025年北京市中考语文试卷(含答案与解析)
- 中科海光:2025年深算智能:海光DCU行业实战手册
- 信息服务费 合同
评论
0/150
提交评论