Android 架构师如何选择网络框架
2017-04-23 15:29
393 查看
简介:我们发现目前android网络开发框架越来越多,其实任何一个网络框架都能满足我们的应用开发需求,但是到底哪一个更好,接下来我们从源码角度来分析,到底哪一个更适合我们。比较:首先我们通过以下几个方面的比较来分析一下(connect实现,线程池管理,可扩展性等)第一方面:首先是connect的实现
volley | okhttp | Retrofit | AsyncHttp | XUtils |
HttpURLConnectionImplHttpsURLConnectionImpl | HttpURLConnectionImplHttpsURLConnectionImpl | HttpURLConnectionImplHttpsURLConnectionImpl | DefaultHttpClient(httpclient) | HttpURLConnectionImplHttpsURLConnectionImpl |
/** * Create an {@link HttpURLConnection} for the specified {@code url}. */ protected HttpURLConnection createConnection(URL url) throws IOException { return (HttpURLConnection) url.openConnection(); }可以看到都是通过URL的openConnection打开的连接,到URL.java中看一下:
public URLConnection openConnection(Proxy proxy) throws IOException { if (proxy == null) { throw new IllegalArgumentException("proxy == null"); } return streamHandler.openConnection(this, proxy); }下面只要知道streamHandler是谁可以了,
void setupStreamHandler() { .... //忽略掉无用代码 // Fall back to a built-in stream handler if the user didn't supply one 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"; //可以看到这里就会实例化okhttp内部的类,接下来就是按照okhttp内部的实现 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); } } else if (protocol.equals("jar")) { streamHandler = new JarHandler(); } if (streamHandler != null) { streamHandlers.put(protocol, streamHandler); } }从上面可以看出来,无论任何框架,只要调用了Url.connect(),在系统源码中自动会使用okhttp的connection去处理这里面需要特殊提出来Retrofix,他与其他的有所不同,是完全使用okhttp实现的,
/** * The factory used to create {@linkplain okhttp3.Call OkHttp calls} for sending a HTTP requests. * Typically an instance of {@link OkHttpClient}. */ public okhttp3.Call.Factory callFactory() { return callFactory; }下面说一下特殊的AnysnHttp,一款老大哥级的网络框架,也是我使用的第一个网络框架,他的底层实现以来httpclient,这个不知道具体什么原因,已经被android废弃了,所以我也不再过多介绍了,简单的列一下代码AsyncHttpRequest.java
private void makeRequest() throws IOException { if (isCancelled()) { return; } // Fixes #115 if (request.getURI().getScheme() == null) { // subclass of IOException so processed in the caller throw new MalformedURLException("No valid URI scheme was provided"); } if (responseHandler instanceof RangeFileAsyncHttpResponseHandler) { ((RangeFileAsyncHttpResponseHandler) responseHandler).updateRequestHeaders(request); } HttpResponse response = client.execute(request, context); if (isCancelled()) { return; } // Carry out pre-processing for this response. responseHandler.onPreProcessResponse(responseHandler, response); if (isCancelled()) { return; } // The response is ready, handle it. responseHandler.sendResponseMessage(response); if (isCancelled()) { return; } // Carry out post-processing for this response. responseHandler.onPostProcessResponse(responseHandler, response); }通过上面的比较,真正连接工作的地方实际上是相同的,所以性能相差是不大的,但是由于其他调用的是okhttp的类,而且是反射等方式,所以okhttp理论上应该是优势最大的,但经过笔者测试,几乎没有差别。第二方面 :下面比较各个内部连接池的实现。首先OkHttp/external/okhttp/okhttp/src/main/java/com/squareup/okhttp/Dispatcher.java
public synchronized ExecutorService getExecutorService() { if (executorService == null) { executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false)); } return executorService; }可以看到是一个无限大的core_size=0的线程池来管理所有的网络请求再看volley
RequestQueue.javamDispatchers = new NetworkDispatcher[threadPoolSize];public class NetworkDispatcher extends Thread可以看到volley简单粗暴的就是new出来几个线程,
再来看xutils
HttpTask.java
private static final PriorityExecutor HTTP_EXECUTOR = new PriorityExecutor(5, true);
public PriorityExecutor(int poolSize, boolean fifo) { BlockingQueue<Runnable> mPoolWorkQueue = new PriorityBlockingQueue<Runnable>(MAXIMUM_POOL_SIZE, fifo ? FIFO_CMP : FILO_CMP); mThreadPoolExecutor = new ThreadPoolExecutor( poolSize, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, mPoolWorkQueue, sThreadFactory); }
可以看到仍然使用的是线程池,只是core_max是5,就是说会始终维持线程,再来看AnysnHttp在AsyncHttpClient.java 中
protected ExecutorService getDefaultThreadPool() {return Executors.newCachedThreadPool();}可以看到使用的是cache的线程池,来进行管理的。可以理解为与okhttp线程池管理方式相同,最后retrofit,因为retrofit底层完全用的是okhttp,所以他和okhttp使用的线程管理方式也是一样的,不再介绍。最后总结一下上面所说的三种线程池管理方式。其实很难说哪个好哪个不好,但是volley的方式过于暴力,1.网络请求频率比较低,仍然有多个线程占用,这是一种浪费,2.当大量的网络请求到来时,线程也没有办法增加,造成请求阻塞,但是他有个好处就是不会因为大量网络请求到来的时候,引起oom对于使用线程池的okhttp和xutils,各有各自的优势,而且都是允许用户自定义线程池的,所以总体来说各有优势。今天先从整体架构角度来分析一下,稍后会对各个细节做进一步的比较。
相关文章推荐
- Android 网络开发框架的选择
- Java&Android开源库代码剖析】のandroid-async-http(如何设计一个优雅的Android网络请求框架,同...
- 如何在Android中添加网络框架OkHttp
- Android 网络开发框架的选择
- android 网络框架 比较 选择
- Android网络框架的选择
- Android 网络操作学习HttpURLConnection与HttpClient及网络框架选择
- Android网络图片加载框架的选择
- 如何在Android开发中高效使用Volley网络框架
- Android 网络开发框架的选择
- android 项目中使用到的网络请求框架以及如何配置好接口URL
- Android网络框架选择(Volley、OkHttp、Retrofit)
- Android网络框架选择(Volley、OkHttp、Retrofit)
- 开发网络爬虫应该如何选择爬虫框架?
- Android 如何封装网络框架(以封装OkHttp为例)
- Android网络图片加载框架的选择
- Android之---项目开发中网络框架的选择
- Android源码分析(五)-----如何从架构师的角度去设计Framework框架
- Android 网络开发框架的选择
- Android 网络开发框架的选择