日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android - 网络基础

發布時間:2024/10/12 Android 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android - 网络基础 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Android網絡編程(一)HTTP協議原理

Android網絡請求心路歷程

?

HttpURLConnection和HttpClient對比:

http://blog.csdn.net/guolin_blog/article/details/12452307

?

HttpURL基本封裝

http://www.jianshu.com/p/3141d4e46240

?

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=6060秒之后緩存過期(相對時間)
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]值

正式使用時按需求也許只包含其中部分字段。
客戶端要根據這些信息儲存這次請求信息。
然后在客戶端發起請求的時候要檢查緩存。遵循下面步驟:

?

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戰斗力翻倍。

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配合框架打出成噸的輸出,這里不再多說。

網絡請求學習到這里我覺得已經到頂了。。

網絡圖片加載優化

對于圖片的傳輸,就像上面的登錄接口的avatar字段,并不會直接把圖片寫在返回內容里,而是給一個圖片的地址。需要時再去加載。

如果你直接用HttpURLConnection去取一張圖片,你辦得到,不過沒優化就只是個BUG不斷demo。絕對不能正式使用。
注意網絡圖片有些特點:

  • 它永遠不會變
    一個鏈接對應的圖片一般永遠不會變,所以當第一次加載了圖片時,就應該予以永久緩存,以后就不再網絡請求。
  • 它很占內存
    一張圖片小的幾十k多的幾M高清無碼。尺寸也是64*64到2k圖。你不能就這樣直接顯示到UI,甚至不能直接放進內存。
  • 它要加載很久
    加載一張圖片需要幾百ms到幾m。這期間的UI占位圖功能也是必須考慮的。
  • 說說我在上面提到的RequestVolley里做的圖片請求處理(沒錯我做了,這部分的代碼可以去github里看源碼)。

    三級緩存

    網上常說三級緩存--服務器,文件,內存。不過我覺得服務器不算是一級緩存,那就是數據源嘛。

    • 內存緩存
      首先內存緩存使用LruCache。LRU是Least Recently Used 近期最少使用算法,這里確定一個大小,當Map里對象大小總和大于這個大小時將使用頻率最低的對象釋放。我將內存大小限制為進程可用內存的1/8.
      內存緩存里讀得到的數據就直接返回,讀不到的向硬盤緩存要數據。

    • 硬盤緩存
      硬盤緩存使用DiskLruCache。這個類不在API中。得復制使用。
      看見LRU就明白了吧。我將硬盤緩存大小設置為100M。


    @Overridepublic 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緩存中沒有所需數據時,調用創造。 @Overrideprotected Bitmap create(String url) {//獲取keyString 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

    以前也覺得這樣已經足夠好直到我遇到下面倆。

    Fresco&Glide

    不用想也知道它們都做了非常完善的優化,重復造輪子的行為很蠢。
    Fresco是Facebook公司的黑科技。光看功能介紹就看出非常強大。使用方法官方博客說的夠詳細了。
    真三級緩存,變換后的BItmap(內存),變換前的原始圖片(內存),硬盤緩存。
    在內存管理上做到了極致。對于重度圖片使用的APP應該是非常好的。
    它一般是直接使用SimpleDraweeView來替換ImageView,呃~侵入性較強,依賴上它apk包直接大1M。代碼量驚人。

    所以我更喜歡Glide,作者是bumptech。這個庫被廣泛的運用在google的開源項目中,包括2014年google I/O大會上發布的官方app。
    這里有詳細介紹。直接使用ImageView即可,無需初始化,極簡的API,豐富的拓展,鏈式調用都是我喜歡的。
    豐富的拓展指的就是這個。
    另外我也用過Picasso。API與Glide簡直一模一樣,功能略少,且有半年未修復的BUG。

    圖片管理方案

    再說說圖片存儲。不要存在自己服務器上面,徒增流量壓力,還沒有圖片處理功能。
    推薦七牛與阿里云存儲(沒用過其它 π__π )。它們都有很重要的一項圖片處理。在圖片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大的高清照片沒意義。

    ?

    轉載于:https://www.cnblogs.com/qlky/p/7237385.html

    總結

    以上是生活随笔為你收集整理的Android - 网络基础的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。