天天看點

Volley源碼初讀

Android Volley源碼初讀

Volley是Google推出的用于處理android中快速響應短暫而又頻繁的網絡請求的架構,雖然不适合做大檔案的上傳與下載下傳,但不能阻止我們學習Volley的思想。

Volley的源碼,類并不是很多,概念也很多,有一定的難度。

  • 首先Volley的位元組數組緩存池:Volley因為處理頻繁的請求,使用了位元組數組池,來避免頻繁重複的記憶體申請,設定緩存池最大的空間,内部維持着一個上次使用的位元組數組的集合和按緩存大小排序的一個緩存區集合。每次需要位元組數組,請去從集合裡取,得到的位元組集合長度至少不低于需要的自己長度,用完就将緩存區還回去,歸還的時候,會做二分查找法,保證緩存集合一直有序,之後還會做緩存空間是否超過限制的判斷,移除使用過的集合中的第一個,其實就是LRU,最近最少使用的一個才會出現在mBuffersByLastUse 這個集合的第一位。
  • 使用原生HttpURLConnection實作,不考慮Android sdk低于9的情況,低于9使用的是HttpClient,不過現在基本沒有sdk小于9的情況。使用HttpURLConnection實作了GET、POST、PUT、DELETE、HEAD、OPTIONS、TRACE、PATCH請求。
  • Volley使用了磁盤緩存,使用url來作為key,每一個key對應一個檔案,檔案都會寫入一些頭資訊,非常巧妙,源碼中寫入頭資訊的時候,使用了很多位運算,例如: |=(位或),&(與),>>、<<等,挺難了解的。

-Volley使用很多鎖,做了很多的并發處理,代碼很優雅,值得我們去學習。

下面我先介紹一些類,幫助學習Volley

Android中流量統計類:TrafficStats

  • 對于Android流量統計來說在2.2版中新加入了TrafficStats類可以輕松擷取,其實本身TrafficStats類也是讀取Linux提供的檔案對象系統類型的文本進行解析。android.net.TrafficStats類中,提供了多種靜态方法,可以直接調用擷取,傳回類型均為 long型,如果傳回等于-1代表 UNSUPPORTED 目前裝置不支援統計。

    Java代碼

static long  getMobileRxBytes()  //擷取通過Mobile連接配接收到的位元組總數,不包含WiFi  
static long  getMobileRxPackets()  //擷取Mobile連接配接收到的資料包總數  
static long  getMobileTxBytes()  //Mobile發送的總位元組數  
static long  getMobileTxPackets()  //Mobile發送的總資料包數  
static long  getTotalRxBytes()  //擷取總的接受位元組數,包含Mobile和WiFi等  
static long  getTotalRxPackets()  //總的接受資料包數,包含Mobile和WiFi等  
static long  getTotalTxBytes()  //總的發送位元組數,包含Mobile和WiFi等  
static long  getTotalTxPackets()  //發送的總資料包數,包含Mobile和WiFi等   
static long  getUidRxBytes(int uid)  //擷取某個網絡UID的接受位元組數  
static long  getUidTxBytes(int uid) //擷取某個網絡UID的發送位元組數   
總接受流量TrafficStats.getTotalRxBytes(), 
總發送流量TrafficStats.getTotalTxBytes()); 
不包含WIFI的手機GPRS接收量TrafficStats.getMobileRxBytes()); 
不包含Wifi的手機GPRS發送量TrafficStats.getMobileTxBytes()); 
某一個程序的總接收量TrafficStats.getUidRxBytes(Uid)); 
某一個程序的總發送量TrafficStats.getUidTxBytes(Uid)); 
如果本裝置不支援統計,将傳回UNSUPPORTED
           
  • Android中設定程序優先級

    Process.setThreadPriority (int priority)

    參考文章:android 設定線程的優先級

    随筆之Android平台上的程序排程探讨

  • AccountManager

    基于Andoird 4.2.2的Account Manager源代碼分析學習:AccountManager的簡要工作流程

  • 優先隊列PriorityBlockingQueue

    Java多線程-工具篇-BlockingQueue

    PriorityBlockingQueue

  • AtomicInteger

    AtomicInteger源碼分析——基于CAS的樂觀鎖實作

  • JAVA中位運算
java中或運算、異或運算、與運算的使用執行個體和解釋如下:

// 1、左移( << )        
// 0000 0000 0000 0000 0000 0000 0000 0101 然後左移2位後,低位補0:
//        // 0000 0000 0000 0000 0000 0000 0001 0100 換算成10進制為20        System.out.println(5 << 2);// 運作結果是20         
// 2、右移( >> ) 高位補符号位        
// 0000 0000 0000 0000 0000 0000 0000 0101 然後右移2位,高位補0:       
 // 0000 0000 0000 0000 0000 0000 0000 0001       
  System.out.println( >> );// 運作結果是1         
  // 3、無符号右移( >>> ) 高位補0        
  // 例如 -5換算成二進制後為:0101 取反加1為1011       
   // 1111 1111 1111 1111 1111 1111 1111 1011        /
   / 我們分别對進行右移位、 -進行右移位和無符号右移位:       
    System.out.println( >> );// 結果是0       
     System.out.println(- >> );// 結果是-1        
     System.out.println(- >>> );// 結果是536870911         
     // 4、位與( & )        
     // 位與:第一個操作數的的第n位于第二個操作數的第n位如果都是1,那麼結果的第n為也為1,否則為0        
     System.out.println( & );// 結果為1        
     System.out.println( & );// 結果為0         
     // 5、位或( | )        
     // 第一個操作數的的第n位于第二個操作數的第n位 隻要有一個是1,那麼結果的第n為也為1,否則為0        
     System.out.println( | );// 結果為7         
     // 6、位異或( ^ )        
     // 第一個操作數的的第n位于第二個操作數的第n位 相反,那麼結果的第n為也為1,否則為0         
     System.out.println( ^ );//結果為6         
      // 7、位非( ~ )        // 操作數的第n位為1,那麼結果的第n位為0,反之。           System.out.println(~5);// 結果為-6     
           
  • LinkedHashMap

    LinkedHashMap

    Volley中就是用了它做LRU緩存。

  • string的intern方法

    java-String中的 intern方法

  • Volatile變量
  • http://wiki.jikexueyuan.com/project/java-concurrency/volatile2.html

感謝上面的各位部落客,幫我解惑!

Volley源碼解析可以去看:

Volley源代碼分析 – 3: 緩存之ByteArrayPool

Volley的cache之硬碟緩存–DiskBasedCache

Volley還有很多不明白的地方,努力搞懂它,加油!