HttpURLConnection对象的获取
2017-09-20 20:21
337 查看
1,获取HttpURLConnection对象
获取HttpURLConnection对象有不同的方法.以下分析都是基于android 6.0
1,通过URL对象获取,
getUrl = new URL("http://•••/"); mSocketAddress = new InetSocketAddress(•••,mProxyPort); Proxy proxy = new Proxy(Proxy.Type.HTTP,mSocketAddress); conn = (HttpURLConnection) getUrl.openConnection(proxy);
2,通过Network对象获取,
getUrl = new URL("http://•••/"); mSocketAddress = new InetSocketAddress(•••,mProxyPort); Proxy proxy = new Proxy(Proxy.Type.HTTP,mSocketAddress); conn = (HttpURLConnection) mNetwork.openConnection(getUrl,proxy);
1.1通过URL对象获取
1.1.1 URL对象构造
URL有6个构造方法,仅有一个String参数的构造方法如下,public URL(String spec) throws MalformedURLException { this((URL) null, spec, null); }
三个参数的URL构造方法主要逻辑如下,
1,调用setupStreamHandler方法获取URLStreamHandler对象,
if (streamHandler == null) { setupStreamHandler(); if (streamHandler == null) { throw new MalformedURLException("Unknown protocol: " + protocol); } }
2,调用URLStreamHandler对象的parseURL方法解析网址,
try { streamHandler.parseURL(this, spec, schemeSpecificPartStart, spec.length()); } catch (Exception e) { throw new MalformedURLException(e.toString()); }
setupStreamHandler的主要逻辑如下,
1,如果streamHandlers Hashtable里面已经保存了就直接从里面取出来就可以了,
streamHandler = streamHandlers.get(protocol); if (streamHandler != null) { return; }
一般一个网址对应一个URLStreamHandler对象。
2,如果URLStreamHandlerFactory对象不为空就可以利用URLStreamHandlerFactory创建URLStreamHandler对象,
if (streamHandlerFactory != null) { streamHandler = streamHandlerFactory.createURLStreamHandler(protocol); if (streamHandler != null) { streamHandlers.put(protocol, streamHandler); return; } }
当然,可以并且只能通过setURLStreamHandlerFactory方法设置URLStreamHandlerFactory对象。
3,如果系统内已经有可以加载URLStreamHandler的包,就优先使用系统的包加载,
String packageList = System.getProperty("java.protocol.handler.pkgs"); ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); if (packageList != null && contextClassLoader != null) { for (String packageName : packageList.split("\\|")) { String className = packageName + "." + protocol + ".Handler"; try { Class<?> c = contextClassLoader.loadClass(className); streamHandler = (URLStreamHandler) c.newInstance(); if (streamHandler != null) { streamHandlers.put(protocol, streamHandler); } return; } catch (IllegalAccessException ignored) { } catch (InstantiationException ignored) { } catch (ClassNotFoundException ignored) { } } }
4,最后根据网址的类型分别构造对应的URLStreamHandler对象.
if (protocol.equals("file")) { streamHandler = new FileHandler(); } else if (protocol.equals("ftp")) { streamHandler = new FtpHandler(); } else if (protocol.equals("http")) { try { String name = "com.android.okhttp.HttpHandler"; streamHandler = (URLStreamHandler) Class.forName(name).newInstance(); } catch (Exception e) { throw new AssertionError(e); } } else if (protocol.equals("https")) { try { String name = "com.android.okhttp.HttpsHandler"; streamHandler = (URLStreamHandler) Class.forName(name).newInstance(); } catch (Exception e) { throw new AssertionError(e); } •••
URLStreamHandler其实是一个抽象类,具体的由各个子类实现。在此,根据不同的请求获取不同的URLStreamHandler子类。
http格式的网址对应的是HttpHandler类。
1.1.2 HttpURLConnection对象
通过URL对象获取HttpURLConnection对象的openConnection方法也有2个,其实就是有没有指定代理(特定APN)的区别,有代理的openConnection调用流程图如下,
URL的openConnection方法如下,
public URLConnection openConnection(Proxy proxy) throws IOException { if (proxy == null) { throw new IllegalArgumentException("proxy == null"); } return streamHandler.openConnection(this, proxy); }
streamHandler就是在上个小节中获取的URLStreamHandler对象,
对于http格式的网址,对应的是URLStreamHandler的子类HttpHandler。
HttpHandler的openConnection方法如下,
protected URLConnection openConnection(URL url, Proxy proxy) throws IOException { if (url == null || proxy == null) { throw new IllegalArgumentException("url == null || proxy == null"); } return newOkUrlFactory(proxy).open(url); }
该方法首先调用newOkUrlFactory方法构造OkUrlFactory对象,然后调用其open方法。newOkUrlFactory方法逻辑如下,
protected OkUrlFactory newOkUrlFactory(Proxy proxy) { OkUrlFactory okUrlFactory = createHttpOkUrlFactory(proxy); ••• okUrlFactory.client().setConnectionPool(configAwareConnectionPool.get()); return okUrlFactory; }
createHttpOkUrlFactory方法主要逻辑如下,
1,构造OkHttpClient对象,
OkHttpClient client = new OkHttpClient();
2,利用OkHttpClient对象设置代理,
if (proxy != null) { client.setProxy(proxy); }
3,利用OkHttpClient对象构造OkUrlFactory对象,
OkUrlFactory okUrlFactory = new OkUrlFactory(client);
OkUrlFactory的open方法如下,
public HttpURLConnection open(URL url) { return open(url, client.getProxy()); }
Open方法也会根据网址构造不同的HttpURLConnection代理对象,
HttpURLConnection open(URL url, Proxy proxy) { String protocol = url.getProtocol(); OkHttpClient copy = client.copyWithDefaults(); copy.setProxy(proxy); if (protocol.equals("http")) return new HttpURLConnectionImpl(url, copy); if (protocol.equals("https")) return new HttpsURLConnectionImpl(url, copy); throw new IllegalArgumentException("Unexpected protocol: " + protocol); }
以http请求为例,通过URLConnection的openConnection方法最后获取的HttpURLConnection对象
其实是代理HttpURLConnectionImpl对象。
1.2通过Network对象获取
Network的openConnection方法逻辑如下,1,利用请求网址调用HttpHandler的createHttpOkUrlFactory方法构造OkUrlFactory对象,
if (protocol.equals("http")) { okUrlFactory = HttpHandler.createHttpOkUrlFactory(proxy); } else if (protocol.equals("https")) { okUrlFactory = HttpsHandler.createHttpsOkUrlFactory(proxy); }
HttpHandler的createHttpOkUrlFactory方法在上个小节已经论述了,此就不赘述了。
2,调用OkUrlFactory对象的open方法创建HttpURLConnectionImpl对象。
return okUrlFactory.open(url);
由此可见,这2中方法最后都会调用OkUrlFactory对象的open方法创建HttpURLConnectionImpl对象,实质完全相同。
相关文章推荐
- 在STRUTS中如何通过request获取从HttpURLConnection写出的流对象
- 在STRUTS中如何通过request获取从HttpURLConnection写出的流对象
- HttpURLConnection获取网络读片,读取本地缓存图片
- HttpURLConnection获取网络图片
- HttpClient和HttpURLConnection获取服务器返回的内容
- android HttpURLConnection编程详解,获取网络图片,html代码查
- 通过URLHttpConnection方式连接网络步骤,获取位图为例
- HttpURLConnection对象和Internet总结如下
- MainAcitvity 获取 HTTPUrlConnection
- 使用HttpURLConnection获取远程URL数据
- HttpURLConnection 获取图片
- HttpUrlConnection获取服务器数据,并返回数据
- 解决httpurlconnection获取网页数据部分中文乱码问题
- Android使用HttpURLConnection获取数据
- java分别通过httpclient和HttpURLConnection获取图片验证码内容
- 使用HttpURLConnection实现在android客户端和服务器之间传递对象
- Android学习之HttpURLConnection对象的使用
- HttpURLConnection重定向,获取及设置cookie
- 使用HttpURLConnection发请求获取数据
- 使用HttpUrlConnection获取数据,Unicode和GZIPInputStream的坑