1. 程式人生 > >android 設計一個簡易的Http網路請求框架

android 設計一個簡易的Http網路請求框架

    一.開發初衷:最近專案中需要用到版本升級這一塊,需要用到一些基本的資料請求與檔案下載功能。之前做專案都是用別人的網路框架,類似retrofit 、 okhttp、 fresco等框架,用的多了,發現這幾個網路請求框架,無非都是

按解決以下幾個問題為導向的:

  1.怎麼發請求?

  2.Cookie的問題。

  3.如何停止請求(好像上面提到的幾個框架沒有停止請求的概念,因為停止請求常用用SOcket長連線協議中,

而http是短連線,只要觸發了請求,就失去了控制一樣。)

  4.請求的併發?

  5.如何管理請求的優先順序(類似http這種協議請求,幾乎可以忽略,請求的優先順序常用於socket協議中)

一直都想寫一個自己的網路請求框架,藉此專案機會,剛好用上了,現將設計思路與原始碼貢獻出來與各位一起交流學習,如有寫的不好,請各位大神,批評指正,謝謝。

 先從回撥介面說起:這個框架中主要有兩類回撥

 第一類為普通的字串請求(類似json都可以視為一種字串,只是一種特殊的格式封裝的資料)

 第二類為檔案類的byte流資料。

package com.example.lxb.hellohttp.httpclient.listener;
/**
 * 回撥基類介面
* Created by lxb on 2017/4/12.
 */
public abstract class BaseRequestListener<T
> { public abstract void onSuccess(T result); public abstract void onFailure(T result); public void onExcetion(T e) { } public void Excetion(String e){ } public void onLoading(long total,long curProgress){ } }

在這個類中將回調共有的的方法封裝出來,如果沒有特殊的回撥行為可以直接用這個基類作為回撥,否則可以自己去擴充套件。

這裡我還寫了一個檔案的監聽器:

package com.example.lxb.hellohttp.httpclient.listener;
/**
 * 檔案監聽器
*
 * Created by lxb on 2017/4/14.
 */
public class FileListener<T> extends BaseRequestListener<T> {


    @Override
public void onSuccess(T result) {

    }

    @Override
public void onFailure(T result) {

    }

    public void Excetion(String e){

    }

    public void onLoading(long total,long curProgress){

    }
}

二。因網路請求本身就是一種I/O操作,並且是一種阻塞式的請求。如果直接放在主執行緒中進行很明顯會影響主執行緒的執行,且android系統中不允許這樣幹。

  鑑於此,本框架中的所有請求均在一個新的執行緒中進行。

 先來看普通字串的請求執行緒:

package com.example.lxb.hellohttp.httpclient.client;
import com.example.lxb.hellohttp.httpclient.HttpClient;
import com.example.lxb.hellohttp.httpclient.handler.MsgHandler;
import com.example.lxb.hellohttp.httpclient.listener.BaseRequestListener;
import com.example.lxb.hellohttp.httpclient.request.RequestParams;
/**
 * 請求執行緒
*
 * Created by lxb on 2017/4/12.
 */
public class RequestThread extends Thread {


    private HttpClient httpClient;
    private MsgHandler response;
    private RequestParams requestParams;
    public RequestParams getRequestParams() {
        return requestParams;
}

    public void setRequestParams(RequestParams requestParams) {
        this.requestParams = requestParams;
}

    public HttpClient getHttpClient() {
        return httpClient;
}

    public void setHttpClient(HttpClient httpClient) {
        this.httpClient = httpClient;
}

    public MsgHandler getResponse() {
        return response;
}

    public void setResponse(MsgHandler response) {
        this.response = response;
}

    @Override
public void run() {
        super.run();
        this.httpClient.execute(requestParams,response);
}
}

檔案請求執行緒:

package com.example.lxb.hellohttp.httpclient.client;
import com.example.lxb.hellohttp.httpclient.HttpClient;
import com.example.lxb.hellohttp.httpclient.handler.MsgHandler;
import com.example.lxb.hellohttp.httpclient.request.FileRequest;
/**
 * 檔案網路請求執行緒
*
 * Created by lxb on 2017/4/13.
 */
public class FileReuqestThread extends Thread {

    private HttpClient httpClient;
    private MsgHandler response;
    private FileRequest fileRequest;
    public FileRequest getFileRequest() {
        return fileRequest;
}

    public void setFileRequest(FileRequest fileRequest) {
        this.fileRequest = fileRequest;
}





    public HttpClient getHttpClient() {
        return httpClient;
}

    public void setHttpClient(HttpClient httpClient) {
        this.httpClient = httpClient;
}

    public MsgHandler getResponse() {
        return response;
}

    public void setResponse(MsgHandler response) {
        this.response = response;
}

    @Override
public void run() {
        super.run();
        this.httpClient.execute(fileRequest,response);
}
}

這裡完全可以使用一個請求執行緒,但為區分不同的請求型別還是寫了兩個類,

兩個類的行為完全一致:

 1.保持真正幹活類例項物件的引用(後面會講,別急^_^)

 2.繫結請求物件

 3.訊息分發控制代碼(主要用來解決android執行緒的通訊問題,後面會講)

既然說到這時直接把請求物件都給出來吧:

普通字元 串請求物件,如果是進行這類的請求,需要在這裡進行設定引數:

package com.example.lxb.hellohttp.httpclient.request;
/**
 * 請求基類
* Created by lxb on 2017/4/13.
 */
public class Request {

    private String URL;
    private String method;
    public String getURL() {
        return URL;
}
    public void setURL(String URL) {
        this.URL = URL;
}


    public String getMethod() {
        return method;
}
    public void setMethod(String method) {
        this.method = method;
}

}

不好意思,上面是一個請求基類,

下面才給出真正的普通字串請求物件:

package com.example.lxb.hellohttp.httpclient.request;
import android.text.TextUtils;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
 * Created by lxb on 2017/4/11.
 */
public class RequestParams extends Request{

    private String defaultMethod = "POST";
    private Map<String,String> params = new HashMap<>();
    public Map<String, String> getParams() {
        return params;
}
    public void setParams(Map<String, String> params) {
        this.params = params;
}

}

檔案請求物件來嘍:

package com.example.lxb.hellohttp.httpclient.request;
/**
 * Created by lxb on 2017/4/13.
 */
public class FileRequest extends Request{


    private String filePath;
    public String getFilePath() {
        return filePath;
}

    public void setFilePath(String filePath) {
        this.filePath = filePath;
}

}

三。再來看看直正的幹活類:

方法分發介面,主要為了顆粒度:

/**
 * 開始執行普通 資料網路請求操作
*
 * @param requestParams
*/
public void execute(RequestParams requestParams, MsgHandler response) {

    this.method = requestParams.getMethod();
    this.URL = requestParams.getURL();
Map<String, String> params = requestParams.getParams();
    if (!params.isEmpty()) {
        paramsData = new JSONObject();
Iterator iter = params.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            try {
                paramsData.put(entry.getKey().toString(), entry.getValue().toString());
} catch (JSONException e) {
                e.printStackTrace();
}
        }
    }

    request(this.method, this.URL, paramsData.toString(), response);
}

/**
 * 預設請求方法採用POST
 *
 * @param method
* @param url
* @param param
* @return
*/
public void request(String method, String url, String param, MsgHandler response) {

    if (method.equals(MsgCode.POST)) {
        doPost(url, param, response);
} else if (method.equals(MsgCode.GET)) {
        doPost(url, param, response);
}
}

四。http請求方式:Post 與 Get (這兩種方式的區別這裡暫且不提)兩種方式,主要是先設定一些請求格式,然後將http中的輸入/輸出流給拿出來進行相應的操作就行了。

http相對socket協議來說簡單很多,它的資料包格式都已經封裝好了,也就是它有固定的訊息頭

但如果採用socket協議的話,訊息頭就需要自己去定義了,不然很容易出現粘包的情況。

post 方式:程式碼中有註釋,不詳細解釋了

/**
 * 向指定 URL 傳送POST方法的請求
*
 * @param url   傳送請求的 URL
 * @param param 請求引數,請求引數應該是 name1=value1&name2=value2 的形式。
* @return 所代表遠端資源的響應結果
* @throws Exception
 */
public void doPost(String url, String param, MsgHandler response) {
    PrintWriter out = null;
BufferedReader in = null;
String result = "";
    try {
        URL realUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("charset", "utf-8");
conn.setUseCaches(false);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setReadTimeout(TIMEOUT_IN_MILLIONS);
conn.setConnectTimeout(TIMEOUT_IN_MILLIONS);
        if (param != null && !param.trim().equals("")) {
            out = new PrintWriter(conn.getOutputStream());
out.print(param);
out.flush();
}
        if (conn.getResponseCode() == 200) {

            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
            while ((line = in.readLine()) != null) {
                result += line;
}
        } else {
            Map<String, String> Failure = new HashMap<>();
Failure.put(MsgCode.Failure_Key, conn.getResponseCode() + "");
ThreadCrossHandler.sendMsgByHandler(response, MsgCode.Failure, Failure);
}

    } catch (Exception e) {
        e.printStackTrace();
Map<String, String> Exception = new HashMap<>();
Exception.put(MsgCode.Exection_Key, e.toString());
ThreadCrossHandler.sendMsgByHandler(response, MsgCode.Exection, Exception);
} finally {
        try {
            if (out != null) {
                out.close();
}
            if (in != null) {
                in.close();
}
        } catch (IOException ex) {
            ex.printStackTrace();
Map<String, String> Exception = new HashMap<>();
Exception.put(MsgCode.Exection_Key, ex.toString());
ThreadCrossHandler.sendMsgByHandler(response, MsgCode.Exection, Exception);
}
    }
    Map<String, String> success = new HashMap<>();
success.put(MsgCode.Success_Key, result);
ThreadCrossHandler.sendMsgByHandler(response, MsgCode.Success, success);
//return result;
}

get 方式:

/**
 * Get請求,獲得返回資料
*
 * @param urlStr
* @return
* @throws Exception
 */
public void doGet(String urlStr, String param, MsgHandler response) {
    PrintWriter out = null;
URL url = null;
HttpURLConnection conn = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
    try {
        url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setReadTimeout(TIMEOUT_IN_MILLIONS);
conn.setConnectTimeout(TIMEOUT_IN_MILLIONS);
conn.setRequestMethod("GET");
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
        if (param != null && !param.trim().equals("")) {
            out = new PrintWriter(conn.getOutputStream());
out.print(param);
out.flush();
}

        if (conn.getResponseCode() == 200) {
            is = conn.getInputStream();
baos = new ByteArrayOutputStream();
            int len = -1;
            byte[] buf = new byte[1024];
            while ((len = is.read(buf)) != -1) {
                baos.write(buf, 0, len);
}
            baos.flush();
Map<String, String> success = new HashMap<>();
success.put(MsgCode.Success_Key, baos.toString());
ThreadCrossHandler.sendMsgByHandler(response, MsgCode.Success, success);
//return baos.toString();
} else {
            Map<String, String> Failure = new HashMap<>();
Failure.put(MsgCode.Failure_Key, conn.getResponseCode() + "");
ThreadCrossHandler.sendMsgByHandler(response, MsgCode.Failure, Failure);
//throw new RuntimeException(" responseCode is not 200 ... ");
}

    } catch (Exception e) {
        //e.printStackTrace();
Map<String, String> Exception = new HashMap<>();
Exception.put(MsgCode.Exection_Key, e.toString());
ThreadCrossHandler.sendMsgByHandler(response, MsgCode.Exection, Exception);
} finally {
        try {
            if (is != null)
                is.close();
} catch (IOException e) {
            Map<String, String> Exception = new HashMap<>();
Exception.put(MsgCode.Exection_Key, e.toString());
ThreadCrossHandler.sendMsgByHandler(response, MsgCode.Exection, Exception);
}
        try {
            if (baos != null)
                baos.close();
} catch (IOException e) {
            Map<String, String> Exception = new HashMap<>();
Exception.put(MsgCode.Exection_Key, e.toString());
ThreadCrossHandler.sendMsgByHandler(response, MsgCode.Exection, Exception);
}
        conn.disconnect();
}

    //return null;
}

上傳檔案方法:主要是注意檔案請求頭的格式,其他沒什麼了

/**
 * 上傳檔案時,注意http協議上傳檔案的協議頭部格式
* <p>
* 示例:例如向主機192.168.1.8上傳圖片格式如下:
* <p>
* POST/logsys/home/uploadIspeedLog!doDefault.html HTTP/1.1
 * Accept: text/plain,
 * Accept-Language: zh-cn
 * Host: 192.168.1.8
 * Content-Type:multipart/form-data;boundary=-----------------------------7db372eb000e2 // step 1
 * User-Agent: WinHttpClient
 * Content-Length: 3693
 * Connection: Keep-Alive
 * <p>
* -------------------------------7db372eb000e2                         //step 2
 * Content-Disposition: form-data; name="file"; filename="kn.jpg"       //step 3
 * Content-Type: image/jpeg
 * (此處省略jpeg檔案二進位制資料...* -------------------------------7db372eb000e2--                       //step 4
 *
 * @param RequestURL
* @param path
* @param response
* @return
*/
public boolean uploadFile(String RequestURL, String path, MsgHandler response) {

    long uploadCount = 0;
    long totalSize = 0;
Map<String, String> Uploadprogress = new HashMap<>();
Uploadprogress.put(MsgCode.Loading_Total_Key, totalSize + "");
File uploadFile = new File(path);
    if (!uploadFile.exists()) return false;
totalSize = uploadFile.length();
String filePostfix = path.substring(path.lastIndexOf("/") + 1, path.length());
String lineEnd = "\r\n";            //嚴格遵循http協議包含換行
String twoHyphens = "--";           //邊界前後必須用--宣告
String boundary = "*****";          //邊界宣告,可自定義
try {
        URL url = new URL(RequestURL);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
/**
         * 允許InputOutput,不使用Cache
         */
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
con.setReadTimeout(TIMEOUT_IN_MILLIONS);
con.setConnectTimeout(TIMEOUT_IN_MILLIONS);
/**
         * 設定http連線屬性,這個是參照傳輸檔案的頭部資訊來寫的
*/
con.setRequestMethod("POST");
con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("Charset", "UTF-8");
con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);  // step1
DataOutputStream dataOutputStream = new DataOutputStream(con.getOutputStream());                  //獲取輸出流通過此處進行檔案上傳
/**
         * 注意格式 即:+邊界+尾,它們的分隔可以自定義,方便分隔一張圖片是否已經上傳完畢
*/
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);    //step 2
dataOutputStream.writeBytes("Content-Disposition: form-data; " + "name=\"file\";filename=\"" + filePostfix + "\"" + lineEnd); //step3
dataOutputStream.writeBytes(lineEnd);     //新增換行,每一句格式都須嚴格遵守
/**
         * 處理檔案
*/
FileInputStream fStream = new FileInputStream(path);
        int bufferSize = 1024;
        byte[] buffer = new byte[bufferSize];
        int length = -1;
        while ((length = fStream.read(buffer)) != -1) {
            dataOutputStream.write(buffer, 0, length);
uploadCount += bufferSize;
Uploadprogress.put(MsgCode.Loading_CurProgress_Key, ((uploadCount * 100) / totalSize) + "");
ThreadCrossHandler.sendMsgByHandler(response, MsgCode.Loading, Uploadprogress);
//System.out.println("369-----------------已上傳:"+((uploadCount * 100) / totalSize));
}

        /**
         * 寫入檔案流時,再寫入一遍檔案尾,告訴伺服器我檔案流上傳完成可以讀取了
*/
dataOutputStream.writeBytes(lineEnd);
dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
fStream.close();
dataOutputStream.flush();
/* 取得Response內容 */
      /*  InputStream is = con.getInputStream();
        int ch;
        StringBuffer b = new StringBuffer();
        while ((ch = is.read()) != -1) {
            b.append((char) ch);
        }*/
dataOutputStream.close();
        int nResponseCode = con.getResponseCode();
        if (nResponseCode == 200) {
            Map<String, String> success = new HashMap<>();
success.put(MsgCode.Success_Key, path);
ThreadCrossHandler.sendMsgByHandler(response, MsgCode.Success, success);
            return true;
} else {
            return false;
}

    } catch (Exception e) {
        System.out.println("上傳失敗:" + e);
Map<String, String> Exception = new HashMap<>();
Exception.put(MsgCode.Exection_Key, e.toString());
ThreadCrossHandler.sendMsgByHandler(response, MsgCode.Exection, Exception);
        return false;
}

}

下載檔案:

/**
 * 下載檔案,並把檔案儲存在制定目錄(-1:下載失敗,0:下載成功,1:檔案已存在)
*
 * @param urlStr
* @param path
* @param fileName
* @param response
* @return
*/
public int downloadFiles(String urlStr, String path, String fileName, MsgHandler response) {
    try {
        FileUtils fileUtils = FileUtils.getInstance();
        if (fileUtils.isFileExist(fileName, path)) return 1;
        else {

            InputStream inputStream = getInputStreamFromUrl(urlStr);
            int fileSize = getInputStreamSizeFromUrl(urlStr);
File resultFile = fileUtils.write2SDFromInput(fileSize, fileName, path, inputStream, response);
            if (resultFile == null) return -1;
}
    } catch (Exception e) {
        System.out.println("讀寫資料異常:" + e);
        return -1;
}
    return 0;
}

/**
 * 通過url獲取輸入流
*
 * @param urlStr
* @return
* @throws IOException
 */
public InputStream getInputStreamFromUrl(String urlStr) throws IOException {

    URL url = new URL(urlStr);
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
InputStream inputStream = urlConn.getInputStream();
    return inputStream;
}

/**
 * 獲取輸入流中檔案大小
*
 * @param urlStr
* @return
* @throws IOException
 */
private int getInputStreamSizeFromUrl(String urlStr) throws IOException {

    URL url = new URL(urlStr);
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
    return urlConn.getContentLength();
}

請求代理類:

package com.example.lxb.hellohttp.httpclient;
import com.example.lxb.hellohttp.httpclient.client.FileReuqestThread;
import com.example.lxb.hellohttp.httpclient.client.RequestThread;
import com.example.lxb.hellohttp.httpclient.handler.MsgHandler;
import com.example.lxb.hellohttp.httpclient.request.FileRequest;
import com.example.lxb.hellohttp.httpclient.request.RequestParams;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
 * 網編請求的代理類
* <p>
* Created by lxb on 2017/4/11.
 */
public class HelloHttp extends HttpClient {


    private static HelloHttp helloHttp;
    private RequestParams requestParams;
    private FileRequest fileRequest;
    private MsgHandler response
            
           

相關推薦

android 設計一個簡易Http網路請求框架

    一.開發初衷:最近專案中需要用到版本升級這一塊,需要用到一些基本的資料請求與檔案下載功能。之前做專案都是用別人的網路框架,類似retrofit 、 okhttp、 fresco等框架,用的多了,發現這幾個網路請求框架,無非都是 按解決以下幾個問題為導向的:   1

Android http網路請求框架搭建

android上網路請求大致分為使用socket和http,普通應用大多使用http或者https,今天主要介紹http,實現目標通過使用http搭建一套簡單的Android網路請求框架。 網路請求部分: Android的網路請求部分我們大致分為: 引數傳遞,網路請求,

Android 9.0/P http 網路請求的問題

Google表示,為保證使用者資料和裝置的安全,針對下一代 Android 系統(Android P) 的應用程式,將要求預設使用加密連線,這意味著 Android P 將禁止 App 使用所有未加密的連線,因此執行 Android P 系統的安卓裝置無論是接收或者傳送流量,未來都不能明碼傳輸,需要使用下一代

學習 :Android 9.0/P http 網路請求的問題

今天在網上看文章的時候看到了這一篇文章,說是Android9.0網路請求會有問題,然後好奇就仔細看了一下。看完之後感覺對自己以後可能有用處就寫這篇文章來記錄一下。以後用到的話可以拿來用一下。 為什麼特意注意了一下這篇文章呢,因為我們公司的請求一直用的是Http而不是用的Https,所以感覺以後升

Android打造一個通用的網路請求引擎HttpUtils

打造一個通用的網路請求引擎HttpUtils 為什麼要打造這個引擎 Xutils的引擎 Okhttp的引擎 使用 為什麼要打造這個引擎 自Android 6.0之後,HttpClient被廢,好多APP是不是出現蛋疼的事,趕緊換掉網路請求

自己動手寫一個輕量級的Android網路請求框架

最近有空在看《App研發錄》一書,良心之作。書中第一部分第二章節講了不少關於網路底層封裝的知識,看後覺得學到了不少乾貨。 索性自己也動手完成了一個非常輕量級的網路請求框架,從該書中獲得了不少幫助。特此記錄,回顧一下思路,整理收穫。OK,一起來看。 就如書中所

Android封裝的一個簡單網路請求框架

最近做畢業設計,沒有用volley框架或則自己以前做專案比較熟悉的beeframework框架的網路請求部分(不得讚一句beeframework的網路請求部分封裝得很好,可以研究一下然後自己仿照著寫寫),本著熟悉和總結andorid一些基礎知識的目的,自己試著寫了一個自己在

Android網路請求框架Retrofit使用介紹

前言 在android開發中,網路請求是最常用的操作之一,目前熱門的網路請求框架有:Retrofit、volley、okhttp、Android-Async-Http,這裡公司專案中用到Retrofit,之前沒了解過,這裡做個學習記錄。 本文參考博文:這是一份很詳細的 Retrofit 2.

Android中retrofit網路請求框架使用

Retrofit 是 Square 公司出品的 HTTP 請求庫, 同時是 Square 是最早開源專案之一, Retrofit 是目前 Android 最流行的 H

Okhttp3網路請求框架+MVP設計模式簡單實戰

Okhttp 目前最新版本的是okhttp:3.4.1,也稱為Okhttp3。  OkHttp是一個精巧的網路請求庫,不僅在介面封裝做的簡單易用,在底層實現上也自成一派。比起原生的HttpURLConnection有過之而無不及,現在已經成為廣大開發者的首選網路通訊庫。 特性 支援ht

Android-volley淺談-從原始碼去了解它為什麼是Google推薦的網路請求框架

今天想總結的是Volley這個網路請求框架,雖然volley論火爆程度比不上okhttp和retrofit 這兩個,並且在日常使用的過程中可能很少有人能去深究為什麼volley是Google 所推薦的網路框架,不管從使用還是從原始碼去理解,我覺得volley都是一款值得去深究

Retrofit 2.0使用詳解,配合OkHttp、Gson,Android最強網路請求框架

1.使用retrofit,需要下載一些jar包 2.介紹這些jar包的作用 在1.x版本的retrofit框架: 只需要Retrofit包和gson-2.4.jar包就行了,那時的Retrofit預設是使用okhttp jar包來網路請

Android網路請求框架Retrofit使用詳解

前言 技術日新月異,一天不跑,就out了! 早點的Android的網路請求框架android-async-http,Volley,XUtils早已被拋諸腦後,到前段時間的OKHttp,再到最近一段時間大火的Retrofit,封裝的越來越好!程式碼越來越簡潔!

深入淺出的理解Android網路請求框架

    以前在寫網路請求的時候,我們經常乾的一件事情就是首先開啟一個執行緒,然後建立一個Handler將網路請求的操作放到一個執行緒中去執行。因為大家都知道網路請求是一個耗時的操作,不能放在主執行緒中去執行,但是我們發現我們用框架去處理網路請求的時候,程式碼量確

Android知識點之網路底層封裝:細數常用的網路請求框架

   Android知識體系更新如此之快,讓人一不小心就會感覺,額,我out了,翻看之前的文章,14年、15年大家討論的網路底層框架都是HttpURLConnection,HttpClient,細數二

Android 網路請求框架 Retrofit2.0實踐使用總結

比較AsyncHttpClient 、Volley、Retrofit三者的請求時間 使用 單次請求 7個請求 25個請求 AsyncHttpClient 941ms 4539ms 13957ms Volley

Android肝帝戰紀之網路請求框架封裝(Retrofit的封裝)

網路請求框架封裝(OkHttp3+Retrofit+loading的封裝) Retrofit的Github連結 點此連結到Github AVLoadingIndicatorView的Github連結(封裝到請求框架中,請求過程中的loading樣式框(

Android 3.0 http網路請求

Android 3.0以上使用http網路請求需要加入如下程式碼: StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().d

OkHttp3-Android網路請求框架常用用法介紹與例項(mob請求天氣預報)

前言: OkHttp是Square開發的第三方庫,用於傳送和接收基於HTTP的網路請求。它建立在Okio庫之上,通過建立共享記憶體池,它嘗試通過標準Java I / O庫更高效地讀取和寫入資料。它還是Retrofit庫的底層庫,為使用基於REST的AP

如何獨立開發一個網路請求框架

1 package com.lghsaleimage; 2 3 import android.graphics.Bitmap; 4 import android.os.Handler; 5 import android.os.Message; 6 import andr