文/Jude95(简书小编),2、提供的恢弘作用

互连网请求是android客户端很紧要的有的。上边从入门级先导介绍下自身Android互连网请求的施行进程。希望能给刚接触Android互连网部分的仇人一些扶植。
正文包涵:

文/Jude95(简书作者)
初稿链接:http://www.jianshu.com/p/3141d4e46240
文章权归小编所有,转发请联系小编得到授权,并标明“简书小编”。

正如的目的:

网络请求是android客户端很要紧的一些。上边从入门级起始介绍下团结Android互联网请求的施行进程。希望能给刚接触Android网络部分的对象一些帮忙。
本文包含:

1、cpu

HTTP请求&响应

既是说从入门级开始就说说Http请求包的布局。
两次呼吁就是向目标服务器发送一串文本。什么样的公文?有上边结构的公文。
HTTP请求包结构

请求包

例子:

    POST /meme.php/home/user/login HTTP/1.1
    Host: 114.215.86.90
    Cache-Control: no-cache
    Postman-Token: bd243d6b-da03-902f-0a2c-8e9377f6f6ed
    Content-Type: application/x-www-form-urlencoded

    tel=13637829200&password=123456

伸手了就会接到响应包(即使对面存在HTTP服务器)
HTTP响应包结构

响应包

例子:

    HTTP/1.1 200 OK
    Date: Sat, 02 Jan 2016 13:20:55 GMT
    Server: Apache/2.4.6 (CentOS) PHP/5.6.14
    X-Powered-By: PHP/5.6.14
    Content-Length: 78
    Keep-Alive: timeout=5, max=100
    Connection: Keep-Alive
    Content-Type: application/json; charset=utf-8

    {"status":202,"info":"\u6b64\u7528\u6237\u4e0d\u5b58\u5728\uff01","data":null}

Http请求格局有

方法 描述
GET 请求指定url的数据,请求体为空(例如打开网页)。
POST 请求指定url的数据,同时传递参数(在请求体中)。
HEAD 类似于get请求,只不过返回的响应体为空,用于获取响应头。
PUT 从客户端向服务器传送的数据取代指定的文档的内容。
DELETE 请求服务器删除指定的页面。
CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS 允许客户端查看服务器的性能。
TRACE 回显服务器收到的请求,主要用于测试或诊断。

常用只有Post与Get。

2、流量

Get&Post

网络请求中大家常用键值对来传输参数(少部分api用json来传递,毕竟不是主流)。
经过地点的牵线,可以看到固然Post与Get本意一个是表单提交一个是呼吁页面,但真相并不曾什么样界别。上面说说参数在那2者的位置。

  • Get方式
    在url中填入参数:

      http://xxxx.xx.com/xx.php?params1=value1&params2=value2
    

居然利用路由

    http://xxxx.xx.com/xxx/value1/value2/value3

那些就是web服务器框架的事了。

  • Post方式
    参数是经过编码放在请求体中的。编码包涵x-www-form-urlencoded
    form-data
    x-www-form-urlencoded的编码格局是这般:
    tel=13637829200&password=123456
    form-data的编码方式是这么:
    —-WebKitFormBoundary7MA4YWxkTrZu0gW
    Content-Disposition: form-data; name=”tel”

      13637829200
      ----WebKitFormBoundary7MA4YWxkTrZu0gW
      Content-Disposition: form-data; name="password"
    
      123456
      ----WebKitFormBoundary7MA4YWxkTrZu0gW
    

x-www-form-urlencoded的优越性就很明显了。可是x-www-form-urlencoded唯其如此传键值对,可是form-data可以传二进制

因为url是存在于请求行中的。
故而Get与Post不同本质就是参数是放在请求行中要么放在请求体
当然无论用哪类都能放在请求头中。一般在请求头中放一些殡葬端的常量。

有人说:

  • Get是明文,Post隐藏
    移动端不是浏览器,不用https全都是公然。
  • Get传递数据上限XXX
    胡说。有限定的是浏览器中的url长度,不是Http协议,移动端请求无影响。Http服务器部分有限量的设置一下即可。
  • Get汉语要求编码
    是真的…要注意。URLEncoder.encode(params, "gbk");

要么提出用post规范参数传递格局。并不曾什么样更可以,只是我们都那样社会更和谐。

地方说的是请求。上边说响应。
呼吁是键值对,但重临数据我们常用Json。
对于内存中的社团数据,肯定要用数据描述语言将目的体系化成文本,再用Http传递,接收端并从文本还原成结构数据。
对象(服务器)<–>文本(Http传输)<–>对象(移动端) 。

服务器重返的数据大部分都是扑朔迷离的结构数据,所以Json最适合。
Json解析库有无数谷歌(Google)的Gson,阿里的FastJson
Gson的用法看这里

HTTP请求&响应

既是说从入门级开首就说说Http请求包的结构。
三遍呼吁就是向目的服务器发送一串文本。什么样的文件?有上面结构的文书。
HTTP请求包结构

图片 1

请求包

例子:

    POST /meme.php/home/user/login HTTP/1.1
    Host: 114.215.86.90
    Cache-Control: no-cache
    Postman-Token: bd243d6b-da03-902f-0a2c-8e9377f6f6ed
    Content-Type: application/x-www-form-urlencoded

    tel=13637829200&password=123456

恳请了就会收到响应包(若是对面存在HTTP服务器)
HTTP响应包结构

图片 2

响应包

例子:

    HTTP/1.1 200 OK
    Date: Sat, 02 Jan 2016 13:20:55 GMT
    Server: Apache/2.4.6 (CentOS) PHP/5.6.14
    X-Powered-By: PHP/5.6.14
    Content-Length: 78
    Keep-Alive: timeout=5, max=100
    Connection: Keep-Alive
    Content-Type: application/json; charset=utf-8

    {"status":202,"info":"\u6b64\u7528\u6237\u4e0d\u5b58\u5728\uff01","data":null}

Http请求格局有

方法 描述
GET 请求指定url的数据,请求体为空(例如打开网页)。
POST 请求指定url的数据,同时传递参数(在请求体中)。
HEAD 类似于get请求,只不过返回的响应体为空,用于获取响应头。
PUT 从客户端向服务器传送的数据取代指定的文档的内容。
DELETE 请求服务器删除指定的页面。
CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS 允许客户端查看服务器的性能。
TRACE 回显服务器收到的请求,主要用于测试或诊断。

常用唯有Post与Get。

3、电量

HttpClient & HttpURLConnection

HttpClient早被放弃了,什么人更好那种题材也唯有经历落后的面试官才会问。具体原因可以看这里

上边说说HttpURLConnection的用法。
最起首接触的就是以此。

    public class NetUtils {
        public static String post(String url, String content) {
            HttpURLConnection conn = null;
            try {
                // 创建一个URL对象
                URL mURL = new URL(url);
                // 调用URL的openConnection()方法,获取HttpURLConnection对象
                conn = (HttpURLConnection) mURL.openConnection();

                conn.setRequestMethod("POST");// 设置请求方法为post
                conn.setReadTimeout(5000);// 设置读取超时为5秒
                conn.setConnectTimeout(10000);// 设置连接网络超时为10秒
                conn.setDoOutput(true);// 设置此方法,允许向服务器输出内容

                // post请求的参数
                String data = content;
                // 获得一个输出流,向服务器写数据,默认情况下,系统不允许向服务器输出内容
                OutputStream out = conn.getOutputStream();// 获得一个输出流,向服务器写数据
                out.write(data.getBytes());
                out.flush();
                out.close();

                int responseCode = conn.getResponseCode();// 调用此方法就不必再使用conn.connect()方法
                if (responseCode == 200) {

                    InputStream is = conn.getInputStream();
                    String response = getStringFromInputStream(is);
                    return response;
                } else {
                    throw new NetworkErrorException("response status is "+responseCode);
                }

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (conn != null) {
                    conn.disconnect();// 关闭连接
                }
            }

            return null;
        }

        public static String get(String url) {
            HttpURLConnection conn = null;
            try {
                // 利用string url构建URL对象
                URL mURL = new URL(url);
                conn = (HttpURLConnection) mURL.openConnection();

                conn.setRequestMethod("GET");
                conn.setReadTimeout(5000);
                conn.setConnectTimeout(10000);

                int responseCode = conn.getResponseCode();
                if (responseCode == 200) {

                    InputStream is = conn.getInputStream();
                    String response = getStringFromInputStream(is);
                    return response;
                } else {
                    throw new NetworkErrorException("response status is "+responseCode);
                }

            } catch (Exception e) {
                e.printStackTrace();
            } finally {

                if (conn != null) {
                    conn.disconnect();
                }
            }

            return null;
        }

        private static String getStringFromInputStream(InputStream is)
                throws IOException {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            // 模板代码 必须熟练
            byte[] buffer = new byte[1024];
            int len = -1;
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            is.close();
            String state = os.toString();// 把流中的数据转换成字符串,采用的编码是utf-8(模拟器默认编码)
            os.close();
            return state;
        }
    }

专注网络权限!被坑了多少次。

<uses-permission android:name="android.permission.INTERNET"/>

Get&Post

网络请求中大家常用键值对来传输参数(少部分api用json来传递,终归不是主流)。
经过位置的牵线,可以见见尽管Post与Get本意一个是表单提交一个是呼吁页面,但真相并从未什么样界别。上面说说参数在那2者的地方。

  • Get方式
    在url中填入参数:

      http://xxxx.xx.com/xx.php?params1=value1&params2=value2
    

    竟然使用路由

      http://xxxx.xx.com/xxx/value1/value2/value3
    

    那个就是web服务器框架的事了。

  • Post方式
    参数是通过编码放在请求体中的。编码包括x-www-form-urlencoded
    form-data
    x-www-form-urlencoded的编码情势是那般:

      tel=13637829200&password=123456
    

    form-data的编码格局是那样:

      ----WebKitFormBoundary7MA4YWxkTrZu0gW
      Content-Disposition: form-data; name="tel"
    
      13637829200
      ----WebKitFormBoundary7MA4YWxkTrZu0gW
      Content-Disposition: form-data; name="password"
    
      123456
      ----WebKitFormBoundary7MA4YWxkTrZu0gW
    

    x-www-form-urlencoded的优越性就很醒目了。可是x-www-form-urlencoded只能传键值对,然则form-data可以传二进制

因为url是存在于请求行中的。
就此Get与Post不相同本质就是参数是放在请求行中依旧放在请求体
自然无论用哪一种都能放在请求头中。一般在请求头中放一些殡葬端的常量。

有人说:

  • Get是明文,Post隐藏
    活动端不是浏览器,不用https全都是大廷广众。
  • Get传递数据上限XXX
    胡说。有限量的是浏览器中的url长度,不是Http协议,移动端请求无影响。Http服务器部分有限制的装置一下即可。
  • Get汉语须求编码
    是真的…要注意。URLEncoder.encode(params, "gbk");

照旧提出用post规范参数传递格局。并没有怎么更优质,只是我们都这么社会更和谐。

地点说的是呼吁。上边说响应。
恳请是键值对,但回来数据大家常用Json。
对于内存中的构造数据,肯定要用数据描述语言将对象连串化成文本,再用Http传递,接收端并从文本还原成结构数据。
对象(服务器)<–>文本(Http传输)<–>对象(移动端) 。

服务器再次回到的数码半数以上都以繁体的社团数据,所以Json最适合。
Json解析库有许多谷歌的Gson,阿里的FastJson
Gson的用法看这里

4、内存占用

同步&异步

那2个概念仅存在于多线程编程中。
android中暗中认可唯有一个主线程,也叫UI线程。因为View绘制只可以在这一个线程内开展。
之所以一旦你阻塞了(某些操作使这些线程在那边运行了N秒)这一个线程,那时期View绘制将不或者举行,UI就会卡。所以要努力幸免在UI线程举办耗时操作。
互联网请求是一个一级耗时操作。
因而地方的Utils类举行网络请求唯有一行代码。

NetUtils.get("http://www.baidu.com");//这行代码将执行几百毫秒。

假定你这么写

        @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String response = Utils.get("http://www.baidu.com");
    }

就会死。。
那就是一同方式。直接耗时操作阻塞线程直到数据接收完结然后回来。Android不允许的。
异步格局:

         //在主线程new的Handler,就会在主线程进行后续处理。
    private Handler handler = new Handler();
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.text);
        new Thread(new Runnable() {
            @Override
            public void run() {
                    //从网络获取数据
                final String response = NetUtils.get("http://www.baidu.com");
                    //向Handler发送处理操作
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                            //在UI线程更新UI
                        textView.setText(response);
                    }
                });
            }
        }).start();
    }

在子线程进行耗时操作,完结后通过Handler将更新UI的操作发送到主线程执行。那就叫异步。Handler是一个Android线程模型中重点的东西,与互联网毫无干系便不说了。关于Handler不明白就先去谷歌一下。
关于Handler原理一篇不错的篇章

但如此写好丢人。异步平常伴随者他的好基友回调
那是经过回调封装的Utils类。

    public class AsynNetUtils {
        public interface Callback{
            void onResponse(String response);
        }

        public static void get(final String url, final Callback callback){
            final Handler handler = new Handler();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    final String response = NetUtils.get(url);
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.onResponse(response);
                        }
                    });
                }
            }).start();
        }

        public static void post(final String url, final String content, final Callback callback){
            final Handler handler = new Handler();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    final String response = NetUtils.post(url,content);
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.onResponse(response);
                        }
                    });
                }
            }).start();
        }
    }

然后选择格局。

    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.webview);
        AsynNetUtils.get("http://www.baidu.com", new AsynNetUtils.Callback() {
            @Override
            public void onResponse(String response) {
                textView.setText(response);
            }
        });

是否优雅很多。
嗯,一个蠢到哭的互联网请求方案成型了。
不灵的地点有数不胜数:

  • 老是都new Thread,new Handler消耗过大
  • 未曾丰盛处理体制
  • 不曾缓存机制
  • 从未有过两全的API(请求头,参数,编码,拦截器等)与调试形式
  • 没有Https

HttpClient & HttpURLConnection

HttpClient早被放弃了,哪个人更好那种题材也只有经历落后的面试官才会问。具体原因可以看这里

下边说说HttpURLConnection的用法。
最早先接触的就是其一。

    public class NetUtils {
        public static String post(String url, String content) {
            HttpURLConnection conn = null;
            try {
                // 创建一个URL对象
                URL mURL = new URL(url);
                // 调用URL的openConnection()方法,获取HttpURLConnection对象
                conn = (HttpURLConnection) mURL.openConnection();

                conn.setRequestMethod("POST");// 设置请求方法为post
                conn.setReadTimeout(5000);// 设置读取超时为5秒
                conn.setConnectTimeout(10000);// 设置连接网络超时为10秒
                conn.setDoOutput(true);// 设置此方法,允许向服务器输出内容

                // post请求的参数
                String data = content;
                // 获得一个输出流,向服务器写数据,默认情况下,系统不允许向服务器输出内容
                OutputStream out = conn.getOutputStream();// 获得一个输出流,向服务器写数据
                out.write(data.getBytes());
                out.flush();
                out.close();

                int responseCode = conn.getResponseCode();// 调用此方法就不必再使用conn.connect()方法
                if (responseCode == 200) {

                    InputStream is = conn.getInputStream();
                    String response = getStringFromInputStream(is);
                    return response;
                } else {
                    throw new NetworkErrorException("response status is "+responseCode);
                }

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (conn != null) {
                    conn.disconnect();// 关闭连接
                }
            }

            return null;
        }

        public static String get(String url) {
            HttpURLConnection conn = null;
            try {
                // 利用string url构建URL对象
                URL mURL = new URL(url);
                conn = (HttpURLConnection) mURL.openConnection();

                conn.setRequestMethod("GET");
                conn.setReadTimeout(5000);
                conn.setConnectTimeout(10000);

                int responseCode = conn.getResponseCode();
                if (responseCode == 200) {

                    InputStream is = conn.getInputStream();
                    String response = getStringFromInputStream(is);
                    return response;
                } else {
                    throw new NetworkErrorException("response status is "+responseCode);
                }

            } catch (Exception e) {
                e.printStackTrace();
            } finally {

                if (conn != null) {
                    conn.disconnect();
                }
            }

            return null;
        }

        private static String getStringFromInputStream(InputStream is)
                throws IOException {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            // 模板代码 必须熟练
            byte[] buffer = new byte[1024];
            int len = -1;
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            is.close();
            String state = os.toString();// 把流中的数据转换成字符串,采用的编码是utf-8(模拟器默认编码)
            os.close();
            return state;
        }
    }

在意网络权限!被坑了有些次。

<uses-permission android:name="android.permission.INTERNET"/>

5、联网时间

HTTP缓存机制

缓存对于移动端是可怜首要的存在。

  • 调减请求次数,减小服务器压力.
  • 地面数据读取速度更快,让页面不会空白几百阿秒。
  • 在无互连网的景况下提供数据。

缓存一般由服务器控制(通过某些方式得以本地控制缓存,比如向过滤器添加缓存控制新闻)。通过在哀告头添加上面多少个字端:

Request

请求头字段 意义
If-Modified-Since: Sun, 03 Jan 2016 03:47:16 GMT 缓存文件的最后修改时间。
If-None-Match: "3415g77s19tc3:0" 缓存文件的Etag(Hash)值
Cache-Control: no-cache 不使用缓存
Pragma: no-cache 不使用缓存

Response

响应头字段 意义
Cache-Control: public 响应被共有缓存,移动端无用
Cache-Control: private 响应被私有缓存,移动端无用
Cache-Control:no-cache 不缓存
Cache-Control:no-store 不缓存
Cache-Control: max-age=60 60秒之后缓存过期(相对时间)
Date: Sun, 03 Jan 2016 04:07:01 GMT 当前response发送的时间
Expires: Sun, 03 Jan 2016 07:07:01 GMT 缓存过期的时间(绝对时间)
Last-Modified: Sun, 03 Jan 2016 04:07:01 GMT 服务器端文件的最后修改时间
ETag: "3415g77s19tc3:0" 服务器端文件的Etag[Hash]值

正规使用时按需要可能只含有其中有的字段。
客户端要依照那一个音讯囤积这一次请求音信。
下一场在客户端发起呼吁的时候要反省缓存。遵从上面步骤:

浏览器缓存机制

小心服务器再次回到304意思是数额没有改观滚去读缓存新闻。
业已年轻的本人为和谐写的互联网请求框架添加完善了缓存机制,还得意,直到有一天自身来看了下边2个东西。(/TДT)/

同步&异步

那2个概念仅存在于十六线程编程中。
android中私行认同唯有一个主线程,也叫UI线程。因为View绘制只可以在这些线程内进行。
故此一旦你阻塞了(某些操作使那些线程在此地运行了N秒)那一个线程,那时期View绘制将不可以开展,UI就会卡。所以要着力防止在UI线程举行耗时操作。
网络请求是一个超人耗时操作。
因此地点的Utils类进行互连网请求唯有一行代码。

NetUtils.get("http://www.baidu.com");//这行代码将执行几百毫秒。

即使你那样写

        @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String response = Utils.get("http://www.baidu.com");
    }

就会死。。
那就是手拉手形式。间接耗时操作阻塞线程直到数据接受达成然后回到。Android差别意的。
异步格局:

         //在主线程new的Handler,就会在主线程进行后续处理。
    private Handler handler = new Handler();
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.text);
        new Thread(new Runnable() {
            @Override
            public void run() {
                    //从网络获取数据
                final String response = NetUtils.get("http://www.baidu.com");
                    //向Handler发送处理操作
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                            //在UI线程更新UI
                        textView.setText(response);
                    }
                });
            }
        }).start();
    }

在子线程举办耗时操作,落成后透过Handler将更新UI的操作发送到主线程执行。那就叫异步。Handler是一个Android线程模型中主要的事物,与网络非亲非故便不说了。关于Handler不精晓就先去谷歌一下。
至于Handler原理一篇不错的文章

但如此写好丢人。异步寻常伴随者他的好基友回调
那是经过回调封装的Utils类。

    public class AsynNetUtils {
        public interface Callback{
            void onResponse(String response);
        }

        public static void get(final String url, final Callback callback){
            final Handler handler = new Handler();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    final String response = NetUtils.get(url);
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.onResponse(response);
                        }
                    });
                }
            });
        }

        public static void post(final String url, final String content, final Callback callback){
            final Handler handler = new Handler();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    final String response = NetUtils.post(url,content);
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.onResponse(response);
                        }
                    });
                }
            });
        }
    }

接下来利用办法。

    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.webview);
        AsynNetUtils.get("http://www.baidu.com", new AsynNetUtils.Callback() {
            @Override
            public void onResponse(String response) {
                textView.setText(response);
            }
        });

是还是不是优雅很多。
哦,一个蠢到哭的网络请求方案成型了。
弱质的地点有这个:

  • 每一回都new Thread,new Handler消耗过大
  • 尚未这些处理体制
  • 尚无缓存机制
  • 从没完善的API(请求头,参数,编码,拦截器等)与调试情势
  • 没有Https

功能点:

Volley&OkHttp

Volley&OkHttp应该是明日最常用的互联网请求库。用法也不行相像。都以用构造请求进入请求队列的章程管理网络请求。

先说Volley:
Volley能够透过这个库开展看重.
Volley在Android 2.3及以上版本,使用的是HttpURLConnection,而在Android
2.2及以下版本,使用的是HttpClient。
Volley的为主用法,网上资料无数,那里推荐郭霖大神的博客
Volley存在一个缓存线程,一个网络请求线程池(暗许4个线程)。
Volley那样从来用支付成效会相比较低,我将本身动用Volley时的种种技术封装成了一个库RequestVolly.
我在这些库上将构造请求的艺术封装为了函数式调用。维持一个大局的伸手队列,拓展一些便利的API。

可是再怎么封装Volley在出力拓展性上从来不能与OkHttp相比较。
Volley截止了翻新,而OkHttp得到了官方的认可,并在持续优化。
就此我最后替换为了OkHttp

OkHttp用法见这里
很和气的API与详尽的文档。
这篇小说也写的很详细了。
OkHttp使用Okio拓展多少传输。都以Square家的。
但并不是直接用OkHttp。Square公司还出了一个Retrofit库同盟OkHttp战斗力翻倍。

HTTP缓存机制

缓存对于移动端是老大主要的留存。

  • 缩减请求次数,减小服务器压力.
  • 本土数据读取速度更快,让页面不会空白几百毫秒。
  • 在无网络的情景下提供数据。

缓存一般由服务器控制(通过某些格局能够本地控制缓存,比如向过滤器添加缓存控制音信)。通过在乞请头添加上面多少个字端:

Request

请求头字段 意义
If-Modified-Since: Sun, 03 Jan 2016 03:47:16 GMT 缓存文件的最后修改时间。
If-None-Match: "3415g77s19tc3:0" 缓存文件的Etag(Hash)值
Cache-Control: no-cache 不使用缓存
Pragma: no-cache 不使用缓存

Response

响应头字段 意义
Cache-Control: public 响应被共有缓存,移动端无用
Cache-Control: private 响应被私有缓存,移动端无用
Cache-Control:no-cache 不缓存
Cache-Control:no-store 不缓存
Cache-Control: max-age=60 60秒之后缓存过期(相对时间)
Date: Sun, 03 Jan 2016 04:07:01 GMT 当前response发送的时间
Expires: Sun, 03 Jan 2016 07:07:01 GMT 缓存过期的时间(绝对时间)
Last-Modified: Sun, 03 Jan 2016 04:07:01 GMT 服务器端文件的最后修改时间
ETag: "3415g77s19tc3:0" 服务器端文件的Etag[Hash]值

正规使用时按必要或然只含有其中一部分字段。
客户端要依据那几个消息囤积这一次请求新闻。
下一场在客户端发起呼吁的时候要反省缓存。遵从上面步骤:

图片 3

浏览器缓存机制

只顾服务器重回304意思是多少尚未更改滚去读缓存新闻。
早已年轻的自己为投机写的网络请求框架添加完善了缓存机制,还自我陶醉,直到有一天我看齐了上面2个东西。(/TДT)/

1、重试机制

Retrofit&RestAPI

Retrofit粗大的简化了互连网请求的操作,它应该说只是一个Rest
API管理库,它是一贯利用OKHttp举行互联网请求并不影响你对OkHttp举行配置。毕竟都以Square公司出品。
RestAPI是一种软件设计风格。
服务器作为资源存放地。客户端去伏乞GET,PUT,
POST,DELETE资源。并且是无状态的,没有session的参预。
挪动端与服务器交互最重点的就是API的安插。比如那是一个正式的登录接口。

Paste_Image.png

你们应该看的出那一个接口对应的伏乞包与响应包大致是何等样子呢。
请求格局,请求参数,响应数据,都很清楚。
选拔Retrofit这一个API可以直观的反映在代码中。

Paste_Image.png

下一场使用Retrofit提需要你的这些接口的落实类
就能一向进行网络请求得到结构数据。

只顾Retrofit2.0相较1.9开展了大量不般配更新。google上大部分科目都是依照1.9的。这里有个2.0的教程。

学科里开展异步请求是选取Call。Retrofit最强劲的地点在于扶助RxJava。就好像我上图中回到的是一个Observable。RxJava上手难度比较高,但用过就再也离不开了。Retrofit+OkHttp+RxJava合作框架打出成吨的出口,那里不再多说。

互连网请求学习到那边我觉得已经到顶了。。

Volley&OkHttp

Volley&OkHttp应该是后天最常用的网络请求库。用法也要命相似。皆以用构造请求到场请求队列的点子管理网络请求。

先说Volley:
Volley可以经过这个库展开正视.
Volley在Android 2.3及以上版本,使用的是HttpURLConnection,而在Android
2.2及以下版本,使用的是HttpClient。
Volley的基本用法,网上资料无数,那里推荐郭霖大神的博客
Volley存在一个缓存线程,一个互连网请求线程池(暗中同意4个线程)。
Volley这样直白用支出作用会比较低,我将我使用Volley时的种种技能封装成了一个库RequestVolly.
本身在那些库上校构造请求的法门封装为了函数式调用。维持一个大局的请求队列,拓展一些有利的API。

只是再怎么封装Volley在效益拓展性上一味不能与OkHttp比较。
Volley甘休了履新,而OkHttp得到了官方的肯定,并在频频优化。
从而我末了替换为了OkHttp

OkHttp用法见这里
很团结的API与详尽的文档。
这篇文章也写的很详细了。
OkHttp使用Okio开展数量传输。都是Square家的。
但并不是一贯用OkHttp。Square公司还出了一个Retrofit库同盟OkHttp战斗力翻倍。

2、提供的壮大功用

互联网图片加载优化

对此图片的传输,就如上边的报到接口的avatar字段,并不会直接把图纸写在回到内容里,而是给一个图纸的地点。必要时再去加载。

假定你间接用HttpURLConnection去取一张图片,你办得到,不过没优化就只是个BUG不断demo。相对无法正式使用。
注意互连网图片有些特点:

  1. 它永远不会变
    一个链接对应的图样一般永远不会变,所以当第三回加载了图片时,就相应予以永久缓存,今后就不再互联网请求。
  • 它很占内存
    一张图片小的几十k多的几M高清无码。尺寸也是64*64到2k图。你不只怕就像此直白突显到UI,甚至无法平昔放进内存。
  • 它要加载很久
    加载一张图纸须要几百ms到几m。那之间的UI占位图作用也是必须考虑的。

说说自家在地方提到的RequestVolley里做的图纸请求处理(没错我做了,这部分的代码可以去github里看源码)。

Retrofit&RestAPI

Retrofit巨大的简化了网络请求的操作,它应当说只是一个Rest
API管理库,它是直接选拔OKHttp举行互连网请求并不影响您对OkHttp举办配备。毕竟都是Square公司出品。
RestAPI是一种软件设计风格。
服务器作为资源存放地。客户端去伏乞GET,PUT,
POST,DELETE资源。并且是无状态的,没有session的参预。
举手投足端与服务器交互最要紧的就是API的设计。比如那是一个专业的记名接口。

图片 4

Paste_Image.png

你们应当看的出这几个接口对应的哀告包与响应包大致是何等体统吗。
恳请格局,请求参数,响应数据,都很清楚。
应用Retrofit那些API可以直观的突显在代码中。

图片 5

Paste_Image.png

下一场使用Retrofit提要求你的那么些接口的兑现类
就能平素举行互连网请求拿到结构数据。

专注Retrofit2.0相较1.9展开了大气不兼容更新。google上绝大多数课程都以根据1.9的。这里有个2.0的教程。

课程里开展异步请求是选拔Call。Retrofit最强劲的地方在于扶助RxJava。就如自身上图中回到的是一个Observable。RxJava上手难度相比高,但用过就再也离不开了。Retrofit+OkHttp+RxJava同盟框架打出成吨的出口,那里不再多说。

互连网请求学习到此处我觉着已经到顶了。。

3、易用性

三级缓存

网上常说三级缓存--服务器,文件,内存。但是我以为服务器不算是一流缓存,这就是数码源嘛。

  • 内存缓存
    先是内存缓存使用LruCache。LRU是Least Recently Used
    近来最少使用算法,那里确定一个高低,当Map里对象大小总和大于这几个大时辰将动用频率低于的目的释放。我将内存大小限制为经过可用内存的1/8.
    内存缓存里读拿到的数额就径直再次来到,读不到的向硬盘缓存要多少。

  • 硬盘缓存
    硬盘缓存使用DiskLruCache。这一个类不在API中。得复制利用。
    看见LRU就明白了吗。我将硬盘缓存大小设置为100M。

      @Override
      public void putBitmap(String url, Bitmap bitmap) {
          put(url, bitmap);
          //向内存Lru缓存存放数据时,主动放进硬盘缓存里
          try {
              Editor editor = mDiskLruCache.edit(hashKeyForDisk(url));
              bitmap.compress(Bitmap.CompressFormat.JPEG, 100, editor.newOutputStream(0));
              editor.commit();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
    
      //当内存Lru缓存中没有所需数据时,调用创造。
      @Override
      protected Bitmap create(String url) {
          //获取key
          String key = hashKeyForDisk(url);
          //从硬盘读取数据
          Bitmap bitmap = null;
          try {
              DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
              if(snapShot!=null){
                  bitmap = BitmapFactory.decodeStream(snapShot.getInputStream(0));
              }
          } catch (IOException e) {
              e.printStackTrace();
          }
          return bitmap;
      }
    

DiskLruCache的原理不再解释了(我还化解了它存在的一个BUG,向Log中添加的多寡增删记录时,最终一条没有出口,导致最后一条缓存平素失效。)

  • 硬盘缓存也绝非多少就回来空,然后就向服务器请求数据。

那就是全方位流程。
但自个儿那样的拍卖方案只怕有众多受制。

  • 图表未经压缩处理直接存储使用
  • 文件操作在主线程
  • 没有周到的图样处理API

以前也认为这么已经充裕好直到自个儿际遇上边俩。

网络图片加载优化

对此图片的传输,似乎上边的记名接口的avatar字段,并不会一贯把图纸写在回到内容里,而是给一个图形的地点。须求时再去加载。

假设你直接用HttpURLConnection去取一张图纸,你办得到,然则没优化就只是个BUG不断demo。相对无法正式使用。
瞩目网络图片有些特点:

  1. 它世代不会变
    一个链接对应的图片一般永远不会变,所以当第一遍加载了图片时,就应该授予永久缓存,以往就不再网络请求。
  2. 它很占内存
    一张图纸小的几十k多的几M高清无码。尺寸也是64*64到2k图。你不能就这么一直展示到UI,甚至无法直接放进内存。
  3. 它要加载很久
    加载一张图片需求几百ms到几m。那里面的UI占位图功效也是必须考虑的。

说说自家在上头提到的RequestVolley里做的图样请求处理(没错我做了,这有的的代码可以去github里看源码)。

4、是否https

Fresco&Glide

不用想也知晓它们都做了要命完美的优化,重复造轮子的行事很蠢。
Fresco是Facebook集团的黑科技。光看作用介绍就观察格外强大。使用方法官方博客说的够详细了。
真三级缓存,变换后的BItmap(内存),变换前的原有图片(内存),硬盘缓存。
在内存管理上成功了极端。对于重度图片采纳的APP应该是尤其好的。
它一般是间接使用SimpleDraweeView来替换ImageView,呃~侵入性较强,着重上它apk包直接大1M。代码量惊人。

由此自个儿更爱好Glide,小编是bumptech。那么些库被周边的应用在google的开源项目中,包蕴二零一四年google
I/O大会上揭晓的官方app。
这里有详实介绍。直接运用ImageView即可,无需初始化,极简的API,充分的进行,链式调用都是自身欣赏的。
加上的开展指的就是这个
其余我也用过Picasso。API与Glide几乎一模一样,功用略少,且有六个月未修复的BUG。

三级缓存

网上常说三级缓存--服务器,文件,内存。可是本身认为服务器不到底拔尖缓存,那就是多少源嘛。

  • 内存缓存
    第一内存缓存使用LruCache。LRU是Least Recently Used
    近日起码使用算法,那里确定一个大小,当Map里对象大小总和大于那么些大时辰将动用功效低于的靶子释放。我将内存大小限制为经过可用内存的1/8.
    内存缓存里读拿到的多少就径直回到,读不到的向硬盘缓存要多少。

  • 硬盘缓存
    硬盘缓存使用DiskLruCache。那么些类不在API中。得复制利用。
    眼见LRU就了然了吗。我将硬盘缓存大小设置为100M。

      @Override
      public void putBitmap(String url, Bitmap bitmap) {
          put(url, bitmap);
          //向内存Lru缓存存放数据时,主动放进硬盘缓存里
          try {
              Editor editor = mDiskLruCache.edit(hashKeyForDisk(url));
              bitmap.compress(Bitmap.CompressFormat.JPEG, 100, editor.newOutputStream(0));
              editor.commit();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
    
      //当内存Lru缓存中没有所需数据时,调用创造。
      @Override
      protected Bitmap create(String url) {
          //获取key
          String key = hashKeyForDisk(url);
          //从硬盘读取数据
          Bitmap bitmap = null;
          try {
              DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
              if(snapShot!=null){
                  bitmap = BitmapFactory.decodeStream(snapShot.getInputStream(0));
              }
          } catch (IOException e) {
              e.printStackTrace();
          }
          return bitmap;
      }
    

    DiskLruCache的原理不再解释了(我还缓解了它存在的一个BUG,向Log中加上的多寡增删记录时,最终一条没有出口,导致最终一条缓存一贯失效。)

  • 硬盘缓存也未尝多少就赶回空,然后就向服务器请求数据。

那就是成套工艺流程。
但自身那样的处理方案如故有诸多受制。

  • 图表未经压缩处理直接存储使用
  • 文件操作在主线程
  • 从未健全的图形处理API

早先也认为那样已经够用好直到我遇上上边俩。

5、是或不是支持reflect api,OkHttp有配套办法

图形管理方案

更何况说图片存储。不要存在本身服务器下边,徒增流量压力,还没有图片处理成效。
推荐七牛阿里云存储(没用过任何
π__π
)。它们都有很关键的一项图片处理。在图片Url上丰富参数来对图片展开局部甩卖再传输。
于是乎(七牛的拍卖代码)

    public static String getSmallImage(String image){
        if (image==null)return null;
        if (isQiniuAddress(image)) image+="?imageView2/0/w/"+IMAGE_SIZE_SMALL;
        return image;
    }

    public static String getLargeImage(String image){
        if (image==null)return null;
        if (isQiniuAddress(image)) image+="?imageView2/0/w/"+IMAGE_SIZE_LARGE;
        return image;
    }

    public static String getSizeImage(String image,int width){
        if (image==null)return null;
        if (isQiniuAddress(image)) image+="?imageView2/0/w/"+width;
        return image;
    }

既可以加速请求速度,又能压缩流量。再同盟Fresco或Glide。完美的图形加载方案。
唯独这就需求您把持有图片都存放在七牛或阿里云,那样也不易。

图形/文件上传也都以利用它们第三方存储,它们都有SDK与法定文档教你。
而是图片一定要减小过后上传。上传1-2M大的高清照片没意义。

Fresco&Glide

不用想也晓得它们都做了要命周密的优化,重复造轮子的行为很蠢。
Fresco是脸书公司的黑科学和技术。光看功效介绍就看到格外强劲。使用格局官方博客说的够详细了。
真三级缓存,变换后的BItmap(内存),变换前的本来面目图片(内存),硬盘缓存。
在内存管理上完毕了无与伦比。对于重度图片选拔的APP应该是那些好的。
它一般是从来运用SimpleDraweeView来替换ImageView,呃~侵入性较强,看重上它apk包直接大1M。代码量惊人。

故此本人更爱好Glide,小编是bumptech。那么些库被大面积的使用在google的开源项目中,蕴含二零一四年google
I/O大会上表露的官方app。
这里有详尽介绍。直接动用ImageView即可,无需初步化,极简的API,丰硕的拓展,链式调用都是自身喜欢的。
丰裕的开展指的就是这个
除此以外我也用过Picasso。API与Glide几乎一模一样,成效略少,且有三个月未修复的BUG。

6、缓存、重试

图形管理方案

再说说图片存储。不要存在自个儿服务器下边,徒增流量压力,还不曾图片处理效果。
推荐七牛阿里云存储(没用过此外π__π
)。它们都有很重点的一项图片处理。在图片Url上加上参数来对图纸展开部分拍卖再传输。
于是乎(七牛的拍卖代码)

    public static String getSmallImage(String image){
        if (image==null)return null;
        if (isQiniuAddress(image)) image+="?imageView2/0/w/"+IMAGE_SIZE_SMALL;
        return image;
    }

    public static String getLargeImage(String image){
        if (image==null)return null;
        if (isQiniuAddress(image)) image+="?imageView2/0/w/"+IMAGE_SIZE_LARGE;
        return image;
    }

    public static String getSizeImage(String image,int width){
        if (image==null)return null;
        if (isQiniuAddress(image)) image+="?imageView2/0/w/"+width;
        return image;
    }

既可以加快请求速度,又能减弱流量。再合作Fresco或Glide。完美的图片加载方案。
只是那就要求您把具有图片都存放在七牛或阿里云,那样也不利。

图片/文件上传也都以选取它们第三方存储,它们都有SDK与合法文档教你。
可是图片一定要削减过后上传。上传1-2M大的高清照片没意义。

7、cookie协理session  id会话协理

8、弱网质量和云浮久安

9、超时时间,三种超时时间   连接超时,响应超时

10、适配各样机型、4.4和事先版本  2.3  4.1 5.0

4种互连网连接形式提供的效应相比较表格:

缓存重试Https/Http稳定性CookieSession

HttpClient√√√Ok√

机关管理Cookie

HttpURLConnectionPOST  ×

GET  √ 4.0以后

√√Ok√

安装请求Cookie

OkHttp√√√Ok√√

Volley√√√Ok√√

Ps:稳定性:多种网络连接格局都在标准广泛应用,都比较稳定。

专门提出的是,在 Froyo(2.2)以前,HttpURLConnection有个基本点
Bug,调用close()函数会影响连接池,导致连日复用失效,所以在 Froyo
以前运用HttpURLConnection须求关闭keepAlive。

除此以外,在 Gingerbread(2.3) HttpURLConnection 专断认同开启了 gzip 压缩,升高了
HTTPS 的习性,Ice Cream Sandwich(4.0) HttpURLConnection
援救了请求结果缓存。

再添加HttpURLConnection自身API相对简便易行,所以对Android来说,在2.3后头提议使用HttpURLConnection,在此以前指出利用HttpClient。

作用对比表格参考的博客:

HttpClient Cookie:

http://zzc1684.iteye.com/blog/2162858

HttpClient 重试机制:

http://blog.csdn.net/weborn/article/details/9112309

Volley源码解析:

http://p.codekk.com/blogs/detail/54cfab086c4761e5001b2542

HttpURLConnection设置请求Cookie:

http://hw1287789687.iteye.com/blog/2240085

OkHttp Cookie管理:

https://segmentfault.com/a/1190000004345545

Volley CookieSession:

http://my.oschina.net/liusicong/blog/361853

HttpClient Session保持:

http://www.flysnow.org/2013/11/21/android-httpclitent-session-keep.html

1、HttpClient  缺点罗列

Apache
HttpClient早就不推荐httpclient,5.0以往干脆放弃,后续会去除。6.0去除了HttpClient。Java开发用HttpClient,官方推荐Android开发用HttpUrlConnection。

DefaultHttpClient和它的兄弟AndroidHttpClient都以HttpClient具体的贯彻类,它们都具有不少的API,而且已毕相比稳定,bug数量也很少。

但同时也由于HttpClient的API数量过多,使得咱们很难在不损坏兼容性的景色下对它举行升高和扩充,所以,近来Android团队在升级和优化HttpClient方面的干活态势并不主动。

很快稳定,不过爱慕资金高昂,故android
开发公司不乐意在维护该库而是转投更为便利的HttpUrlConnection。

2、HttpURLConnection

HttpURLConnection是一种多用途、轻量极的HTTP客户端,使用它来拓展HTTP操作可以适用于一大半的应用程序。即使HttpURLConnection的API提供的相比较不难,可是同时那也使得大家得以特别便于地去接纳和伸张它。

可是在Android
2.2版本在此之前,HttpURLConnection一向留存着一些令人发指痛恨的bug。比如说对一个可读的InputStream调用close()方法时,就有大概会造成连接池失效了。那么我们普通的消除办法就是直接禁用掉连接池的意义:

在Android
4.0本子中,大家又添加了一些响应的缓存机制。当缓存被安装后(调用HttpResponseCache的install()方法),所有的HTTP请求都会满意以下二种情况:

比较轻便,灵活,易于扩充

在3.0后以及4.0中都举办了创新,如对HTTPS的支持

在4.0中,还增加了对缓存的支撑

在android
2.2及以下版本中HttpUrlConnection存在着有些bug,所以指出在android
2.3后头使用HttpUrlConnection,2.3事先使用HttpClient。

3、OkHttp可取较多

OkHttp是一个现代,赶快,高效的Http
client,协理HTTP/2以及SPDY(SPDY介绍网址:https://zh.wikipedia.org/wiki/SPDYSPDY(发音如塞尔维亚共和国语:speedy),一种开放网络传输协议,由Google支付),它为您做了许多的业务。

OKHttp是Android版Http客户端。万分飞速,支持SPDY、连接池、GZIP和HTTP缓存。

支撑SPDY,可以统一多少个到同一个主机的哀告

OkHttp完结的多多技艺如:连接池,gziping,缓存等就领悟网络有关的操作是何其繁杂了。

OkHttp扮演着传输层的剧中人物。

OkHttp使用Okio来大大简化数据的拜访与仓储,Okio是一个增高
java.io 和 java.nio的库。

OkHttp
处理了诸多网络疑难杂症:会从广大常用的连日难题中自动回复。借使您的服务器配置了三个IP地址,当第二个IP连接战败的时候,OkHttp会自动尝试下一个IP。

OkHttp还处理了代理服务器难题和SSL握手战败难题。

OkHttp是一个Java的HTTP+SPDY客户端开发包,同时也接济Android。需求Android
2.3以上

OKHttp是Android版Http客户端。非凡便捷,接济SPDY、连接池、GZIP和 HTTP
缓存。

暗中同意情状下,OKHttp会自动处理大规模的互连网难题,像二次一而再、SSL的握手难题。

假定你的应用程序中融为一炉了OKHttp,Retrofit专断承认会使用OKHttp处理任何网络层请求。

从Android4.4发端HttpURLConnection的最底层完毕利用的是okHttp

缓存响应防止再度的互联网请求

当前,该包裹库志帮忙:

•     一般的get请求

•     一般的post请求

•     基于Http的文书上传

•     文件下载

•     上传下载的进程回调

•     加载图片

•     帮助请求回调,直接重临对象、对象集合

•     支持session的保持

•     接济自签约网站https的拜访,提供格局设置下证件就行

•     辅助撤废某个请求

干什么要做缓存,大概说有如何便宜?

减掉服务器负荷,下跌延迟晋升用户体验。

复杂的缓存策略会基于用户眼下的互连网状态使用差异的缓存策略,比如在2g互联网很差的意况下,进步缓存使用的日子;不用的施用、业务须要、接口所急需的缓存策略也会不平等,有的要保障数据的实时性,所以不大概有缓存,有的你可以缓存5秒钟,等等。你要依据具体景况所需数据的时效性景况提交区其余方案。当然你也足以整个都一律的缓存策略,看您本人。

4、Volley

Volley是一个简化互连网任务的库。他负责处理请求,加载,缓存,线程,同步等题材。它可以拍卖JSON,图片,缓存,文本源,支持一定程度的自定义。

Volley在Android 2.3及以上版本,使用的是HttpURLConnection,而在Android
2.2及以下版本,使用的是HttpClient。

Volley的中央用法,网上资料无数,那里推荐郭霖大神的博客

Volley存在一个缓存线程,一个互联网请求线程池(暗中同意4个线程)。

Volley这样直白用支付功用会比较低,我将自我使用Volley时的各类技术封装成了一个库RequestVolly.

自家在那些库中校构造请求的法门封装为了函数式调用。维持一个大局的伸手队列,拓展一些惠及的API。

唯独再怎么封装Volley在效劳拓展性上一直不或然与OkHttp相比较。

Volley甘休了履新,而OkHttp拿到了法定的认同,并在相连优化。由此我最后替换为了OkHttp

OkHttp使用Okio进行多少传输。都以Square家的。

但并不是直接用OkHttp。Square公司还出了一个Retrofit库合营OkHttp战斗力翻倍。

网络加载库:Picasso、Fresco,所以我更欣赏Glide

不过以后主流的网络请求都以用Volley,OkHttp呼声也很高。

Volley是为RPC网络操作而安顿的,适用于短时操作。

Volley默许在Froyo上选择Apache
Http stack作为其传输层,在Gingerbread及事后的版本上行使HttpURLConnection stack作为传输层。原因是在差其余安卓版本中那三种http
stack各自存在一些难题。

Volley可以轻松设置OkHttp作为其传输层。

Volley是谷歌(Google)开发的。

Volley可以说是把AsyncHttpClient和Universal-Image-Loader的亮点集于了一身,既可以像AsyncHttpClient一样万分简单地开展HTTP通讯,也可以像Universal-Image-Loader一样自在加载互连网上的图纸。除了不难易用之外,Volley在性质方面也开展了大幅面的调整,它的规划目的就是万分适合去举行数据量不大,但通讯频仍的互连网操作,而对此大数据量的互连网操作,比如说下载文件等,Volley的显现就会充裕不佳

Volley提供了:JsonObjectRequest、JsonArrayRequest、StringRequest、ImageRequest、NetworkImageView等Request形式。

Volley的独到之处很多,可进展、结构合理、逻辑清晰、能辨识缓存、通过合并的法子,获取互连网数据,包涵且不压制文本、图片等资源。用了一段时间,果断放任从前用过的任何框架。

Volley在一方始创办请求队列的经过中,须求成立互联网线程和缓存线程,同时还亟需伊始化基于Disk的缓存,那中档有雅量的资源开发和IO操作,所有才会慢。

4种办法的相比较:

1、HttpClient:在Android
2.2版本以前,HttpClient拥有较少的bug,因而利用它是最好的精选。

2、HttpURlConnection:而在Android
2.3版本及其后,HttpURLConnection则是极品的取舍。它的API简单,体积较小,因此特别适用于Android项目。

对于新的应用程序应该进一步偏向于选用HttpURLConnection因为在此后的工作中间大家也会将越多的大运放在优化HttpURLConnection上边。

谷歌(谷歌(Google))协调也是引进用HttpUrlConnection,对它举办了汪洋的优化,那个从安卓的扶持文档可以看出来:

http://developer.android.com/reference/java/net/HttpURLConnection.html

3、OkHttp:是一个争辨成熟的化解方案,大家更有理由相信OkHttp的有力。

Android4.4的源码中可以见见HttpURLConnection已经替换成OkHttp完成了。

OkHttp 处理了无数网络疑难杂症:会从过多常用的连九歌题中活动苏醒。

设若您的服务器配置了八个IP地址,当首个IP连接失利的时候,OkHttp会自动尝试下一个IP。

OkHttp还处理了代理服务器难点和SSL握手失利难题。

运用 OkHttp 无需重写你程序中的互联网代码。

OkHttp达成了大约和java.net.HttpURLConnection一样的API。

实则未来嘛,两者都休想,就用Okhttp

HttpUrlConnection

当今的底部完结就是通过Okhttp

互连网请求框架接济的功能:

1、协助自定义请求的Header

2、支持Http的焦点请求方法:GET、POST

3、协助文件上传和下载

4、可以加载图片

5、辅助多职责网络请求操做

6、援救缓存

7、援救请求回调

8、支持session的保持

互联网优化指出点:

1、连接复用节省连接建马上间,如开启keep-alive

2、不用域名,用IP直连省去DNS解析进度,依据域名拿到IP地址

参考博客:

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html

http://blog.csdn.net/zhangcanyan/article/details/51661448

一、品质目的相比较

测试手机:金立MI3(4.4.4)、魅蓝2(5.1)

测试版本:书旗Android 9.9.0

测试环境:直连下wifi访问

测试方法:安装并开启易测APP,安装互联网框架apk,举办联网请求(http://www.csdn.net/),请求多次进行测试。

测试结果总计:测试3次。

误差表达:第三方软件总括,受后台应用影响,存在一定误差。

1、CPU占用

误差表明:第三方软件总结,受后台应用影响,存在必然误差。

敲定:测试机型完全上CPU占用率,OkHttp的网络请求略低于其它联网格局。

2、内存消耗

误差表达:第三方软件总结,受后台应用影响,存在一定误差。

结论:测试机型完全上内存占用意况,在OPPO手机上,OkHttp的网络请求消耗内存略低于其余联网情势。在OPPO手机上,内存消耗略高于其它方法。突显出测试机型内存消耗表现各异。

3、电量消耗

误差表达:第三方软件总括,受后台应用影响,存在一定误差。

结论:OkHttp的网络请求消耗的电量百分比在略低于其余联网方式,消耗的总电量在华为手机上当先此外联网格局,在小米手机上略低于其余联网形式。消耗能量的差别不大,在0.5mah以内。

4、流量消耗

误差表达:网络请求的发送和选拔流量存在一定误差。

结论:

1、网络发送流量HttpURLConnection最高,Volley次之,OKHttp首位,HttpClient最少。不过,数据量差异不大,零点几的呼吁差异。

2、累积接收流量HttpClient最大,HttpURLConnection和Volley相同,OkHttp略大于前两者。

5、联网平均耗时

误差表明:互联网的场所恐怕会影响网络请求时间。

敲定:互连网请求平均耗时HttpClient最大,HttpURLConnection最小,Volley平均比前者高10ms~20ms,OkHttp比Volley高20ms~40ms。

综上得出最后敲定:

1、对于新的应用程序,应该越来越偏向于采纳HttpURLConnection因为在以后的干活当中谷歌也会将越来越多的大运放在优化HttpURLConnection下边。

谷歌(谷歌(Google))温馨也是援引用HttpUrlConnection,对它举办了大气的优化,那几个从安卓的支援文档可以看出来:

http://developer.android.com/reference/java/net/HttpURLConnection.html

2、对于已经成熟的应用,Volley甘休了立异,而OkHttp得到了官方的认可,并在相连优化。

为此我提出选择OkHttp,以往风行稳定版为3.2.0

相关文章