導航:首頁 > 操作系統 > android網路請求方式

android網路請求方式

發布時間:2022-10-03 15:52:02

android網路操作的幾種方法

第一種方式:使用HttpURLConnection進行聯網操作

這個方法需要我們手動構建一個http請求包,發送到指定的伺服器

get方式

2.post方式

㈡ Android網路請求知識(三)授權,TCP/IP,HTTPS建立過程

由身份或持有的令牌確認享有的許可權,登錄過程實質上的目的也是為了確認許可權。

Cookie是客戶端給伺服器用的,setCookie是伺服器給客戶端用的。cookie由伺服器處理,客戶端負責存儲

客戶端發送cookie:賬戶和密碼
服務端收到後確認登錄setCookie:sessionID=1,記下sessionID
客戶端收到sessionID後記錄,以後請求服務端帶上對比記錄下sessionID,說明已經登錄

會話管理:登錄狀態,購物車
個性化:用戶偏好,主題
Tracking:分析用戶行為

XXS:跨腳本攻擊,及使用JavaScript拿到瀏覽器的cookie之後,發送到自己的網站,以這種方式來盜用用戶Cookie。Server在發送Cookie時,敏感的Cookie加上HttpOnly,這樣Cookie只能用於http請求,不能被JavaScript調用
XSRF:跨站請求偽造。Referer 從哪個網站跳轉過來

兩種方式:Basic和Bearer

首先第三方網站向授權網站申請第三方授權合作,拿到授權方頒發的client_id和client_secret(一般都是appid+appkey的方式)。

在這就過程中申請的client_secret是伺服器持有的,安全起見不能給客戶端,用服務端去和授權方獲取用戶信息,再傳給客戶端,包括④,⑤的請求過程也是需要加密的。這才是標準的授權過程。
有了access_token之後,就可以向授權方發送請求來獲取用戶信息

步驟分析就是上面的內容,這里把第4,6,8請求的參數分析一下
第④步參數:
response_type:指授權類型,必選,這里填固定值『code』
client_id:指客戶端id,必選,這里填在平台報備時獲取的appid
redirect_uri:指重定向URI,可選
scope:指申請的許可權范圍,可選
state:指客戶端當前狀態,可選,若填了,則認證伺服器會原樣返回該值

第⑥步參數:
grant_type:指使用哪種授權模式,必選,這里填固定值『authorization_code』
code:指從第⑤步獲取的code,必選
redirect_uri:指重定向URI,必選,這個值需要和第④步中的redirect_uri保持一致
client_id:指客戶端id,必選,這里填在平台報備時獲取的appid
client_secret:指客戶端密鑰,必選,這里填在平台報備時獲取的appkey

第⑧步參數:
access_token:指訪問令牌,必選,這里填第⑦步獲取的access_token
token_type:指令牌類型,必選,大小寫不敏感,bearer類型 / mac類型
expires_in:指過期時間,單位秒,當其他地方已設置過期時間,此處可省略該參數
refresh_token:指更新令牌,可選,用即將過期token換取新token
scope:指許可權范圍,可選,第④步中若已申請過某許可權,此處可省略該參數

我們在上面的第八步中會有refresh_token的參數,這個在實際操作中也比較常見

有時候我們在自己的項目中,將登陸和授權設計成類似OAuth2的過程,不過去掉Authorization code。登陸成功返回access_token,然後客戶端再請求時,帶上access_token。

我們常常會說到TCP/IP,那到底是什麼呢。這就需要講到網路分層模型。TCP在傳輸層,IP在網路層。那為什麼需要分層?因為網路不穩定,導致需要重傳的問題。為了提高傳輸效率我們就需要分塊,在傳輸層中就會進行分塊。TCP還有兩個重要的內容就是三次握手,四次分手。

HTTPS 協議是由 HTTP 加上TLS/SSL協議構建的可進行加密傳輸、身份認證的網路協議,主要通過數字證書、加密演算法、非對稱密鑰等技術完成互聯網數據傳輸加密,實現互聯網傳輸安全保護

1.客戶端通過發送Client Hello報文開始SSL通信。報文中包含客戶端支持的SSL的指定版本、加密組件列表(所使用的加密演算法及密鑰長度),客戶端隨機數,hash演算法。

2.伺服器可進行SSL通信時,會以Server Hello報文作為應答。和客戶端一樣,在報文中包含SSL版本以及加密組件,服務端隨機數。伺服器的加密組件內容是從接收到客戶端加密組件內篩選出來的。

3.之後伺服器發送Certificate報文。報文中包含公開密鑰證書。一般實際有三層證書嵌套,其實像下面圖二直接用根證書機構簽名也是可以的,但是一般根證書機構比較忙,需要類似中介的證書機構來幫助。

4.最後伺服器發送Server Hello Done報文通知客戶端,最初階段的SSL握手協商部分結束。

5.SSL第一次握手結束後,客戶端以Client Key Exchange報文作為回應。報文中包含通信加密中使用的一種被稱為Pre-master secret的隨機密碼串。該報文已用步驟3中的公開密鑰進行加密。

6.接著客戶端繼續發送Change Cipher Spec報文。該報文會提示伺服器,在此報文之後的通信會採用Pre-master secret密鑰加密。

7.客戶端發送Finished報文。該報文包含連接至今全部報文的整體校驗值。這次握手協商是否能夠成功,要以伺服器是否能夠正確解密報文作為判定標准。

8.伺服器同樣發送Change Cipher Spec報文。

9.伺服器同樣發送Finished報文。

10.伺服器和客戶端的Finished報文交換完畢之後,SSL連接就算建立完成。當然,通信會受到SSL的保護。從此處開始進行應用層協議的通信,即發送HTTP響應。

11.應用層協議通信,即發送HTTP響應。

12.最後由客戶端斷開連接。斷開連接時,發送close_notify報文。這步之後再發送TCP FIN報文來關閉與TCP的通信。

利用客戶端隨機數,服務端隨機數,per-master secret隨機數生成master secret,再生成客戶端加密密鑰,服務端加密密鑰,客戶端MAC secert,服務端MAC secert。MAC secert用於做報文摘要,這樣能夠查知報文是否遭到篡改,從而保護報文的完整性。

Android網路請求知識(一)HTTP基礎概念
Android網路請求知識(二)對稱和非對稱加密、數字簽名,Hash,Base64編碼
Android網路請求知識(三)授權,TCP/IP,HTTPS建立過程

㈢ android 網路請求數據一般寫在哪

一、需要用到的場景 在jQuery中使用$.post()就可以方便的發起一個post請求,在android程序中有時也要從伺服器獲取一些數據,就也必須得使用post請求了。 二、需要用到的主要類 在android中使用post請求主要要用到的類是HttpPost、HttpResponse、EntityUtils 三、主要思路 1、創建HttpPost實例,設置需要請求伺服器的url。 2、為創建的HttpPost實例設置參數,參數設置時使用鍵值對的方式用到NameValuePair類。 3、發起post請求獲取返回實例HttpResponse 4、使用EntityUtils對返回值的實體進行處理(可以取得返回的字元串,也可以取得返回的byte數組) 代碼也比較簡單,注釋也加上了,就直接貼出來了 [java] package com.justsy.url; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils; import android.app.Activity; import android.os.Bundle; public class HttpURLActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); System.out.println("start url..."); String url = "192.168.2.112:8080/JustsyApp/Applet"; // 第一步,創建HttpPost對象 HttpPost httpPost = new HttpPost(url); // 設置HTTP POST請求參數必須用NameValuePair對象 List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("action", "downloadAndroidApp")); params.add(new BasicNameValuePair("packageId", "89dcb664-50a7-4bf2-aeed-49c08af6a58a")); params.add(new BasicNameValuePair("uuid", "test_ok1")); HttpResponse httpResponse = null; try { // 設置httpPost請求參數 httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); httpResponse = new DefaultHttpClient().execute(httpPost); //System.out.println(httpResponse.getStatusLine().getStatusCode()); if (httpResponse.getStatusLine().getStatusCode() == 200) { // 第三步,使用getEntity方法活得返回結果 String result = EntityUtils.toString(httpResponse.getEntity()); System.out.println("result:" + result); T.displayToast(HttpURLActivity.this, "result:" + result); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } System.out.println("end url..."); setContentView(R.layout.main); } } ADD:使用HttpURLConnection 進行post請求 [java] String path = "192.168.2.115:8080/android-web-server/httpConnectServlet.do?PackageID=89dcb664-50a7-4bf2-aeed-49c08af6a58a"; URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setConnectTimeout(5000); System.out.println(conn.getResponseCode()); ============================================================================================================================ 通過get和post方式向伺服器發送請求 首先說一下get和post的區別 get請求方式是將提交的參數拼接在url地址後面,例如/index.jsp?num=23&jjj=888; 但是這種形式對於那種比較隱私的參數是不適合的,而且參數的大小也是有限制的,一般是1K左右吧,對於上傳文件 就不是很適合。 post請求方式是將參數放在消息體內將其發送到伺服器,所以對大小沒有限制,對於隱私的內容也比較合適。 如下Post請求 POST /LoginCheck HTTP/1.1 Accept: text/html, application/xhtml+xml, */* Referer: 192.168.2.1/login.asp Accept-Language: zh-CN User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; BOIE9;ZHCN) Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip, deflate Host: 192.168.2.1 Content-Length: 39 Connection: Keep-Alive Cache-Control: no-cache Cookie: language=en Username=admin&checkEn=0&Password=admin //參數位置 在android中用get方式向伺服器提交請求: 在android模擬器中訪問本機中的tomcat伺服器時,注意:不能寫localhost,因為模擬器是一個單獨的手機系統,所以要寫真是的IP地址。 否則無法訪問到伺服器。 //要訪問的伺服器地址,下面的代碼是要向伺服器提交用戶名和密碼,提交時中文先要經過URLEncoder編碼,因為模擬器默認的編碼格式是utf-8 //而tomcat內部默認的編碼格式是ISO8859-1,所以先將參數進行編碼,再向伺服器提交。 private String address = "192.168.2.101:80/server/loginServlet"; public boolean get(String username, String password) throws Exception { username = URLEncoder.encode(username);// 中文數據需要經過URL編碼 password = URLEncoder.encode(password); String params = "username=" + username + "&password=" + password; //將參數拼接在URl地址後面 URL url = new URL(address + "?" + params); //通過url地址打開連接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //設置超時時間 conn.setConnectTimeout(3000); //設置請求方式 conn.setRequestMethod("GET"); //如果返回的狀態碼是200,則一切Ok,連接成功。 return conn.getResponseCode() == 200; } 在android中通過post方式提交數據。 public boolean post(String username, String password) throws Exception { username = URLEncoder.encode(username);// 中文數據需要經過URL編碼 password = URLEncoder.encode(password); String params = "username=" + username + "&password=" + password; byte[] data = params.getBytes(); URL url = new URL(address); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(3000); //這是請求方式為POST conn.setRequestMethod("POST"); //設置post請求必要的請求頭 conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");// 請求頭, 必須設置 conn.setRequestProperty("Content-Length", data.length + "");// 注意是位元組長度, 不是字元長度 conn.setDoOutput(true);// 准備寫出 conn.getOutputStream().write(data);// 寫出數據 return conn.getResponseCode() == 200;

㈣ android 怎麼用封裝好的網路請求

android中網路通信分為socket編程和http編程,這里只介紹htt方面。網路請求方式可分為get請求,post兩種請求方式,GET方式在進行數據請求時,會把數據附加到URL後面傳遞給伺服器,比如常見的:http://XXX.XXX.XXX/XX.aspx?id=1,POST方式則是將請求的數據放到HTTP請求頭中,作為請求頭的一部分傳入伺服器。
所以,在進行HTTP編程前,首先要明確究竟使用的哪種方式進行數據請求的。

android中Http編程有兩種:1、HttpURLConnection;2、HttpClient

㈤ android中發送網路請求的技術有哪些

Get方式:

[java] view plain
// Get方式請求
public static void requestByGet() throws Exception {
String path = "https://reg.163.com/logins.jsp?id=helloworld&pwd=android";
// 新建一個URL對象
URL url = new URL(path);
// 打開一個HttpURLConnection連接
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
// 設置連接超時時間
urlConn.setConnectTimeout(5 * 1000);
// 開始連接
urlConn.connect();
// 判斷請求是否成功
if (urlConn.getResponseCode() == HTTP_200) {
// 獲取返回的數據
byte[] data = readStream(urlConn.getInputStream());
Log.i(TAG_GET, "Get方式請求成功,返回數據如下:");
Log.i(TAG_GET, new String(data, "UTF-8"));
} else {
Log.i(TAG_GET, "Get方式請求失敗");
}
// 關閉連接
urlConn.disconnect();
}

Post方式:

[java] view plain
// Post方式請求
public static void requestByPost() throws Throwable {
String path = "https://reg.163.com/logins.jsp";
// 請求的參數轉換為byte數組
String params = "id=" + URLEncoder.encode("helloworld", "UTF-8")
+ "&pwd=" + URLEncoder.encode("android", "UTF-8");
byte[] postData = params.getBytes();
// 新建一個URL對象
URL url = new URL(path);
// 打開一個HttpURLConnection連接
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
// 設置連接超時時間
urlConn.setConnectTimeout(5 * 1000);
// Post請求必須設置允許輸出
urlConn.setDoOutput(true);
// Post請求不能使用緩存
urlConn.setUseCaches(false);
// 設置為Post請求
urlConn.setRequestMethod("POST");
urlConn.setInstanceFollowRedirects(true);
// 配置請求Content-Type
urlConn.setRequestProperty("Content-Type",
"application/x-www-form-urlencode");
// 開始連接
urlConn.connect();
// 發送請求參數
DataOutputStream dos = new DataOutputStream(urlConn.getOutputStream());
dos.write(postData);
dos.flush();
dos.close();
// 判斷請求是否成功
if (urlConn.getResponseCode() == HTTP_200) {
// 獲取返回的數據
byte[] data = readStream(urlConn.getInputStream());
Log.i(TAG_POST, "Post請求方式成功,返回數據如下:");
Log.i(TAG_POST, new String(data, "UTF-8"));
} else {
Log.i(TAG_POST, "Post方式請求失敗");
}
}

org.apache.http包中的HttpGet和HttpPost類

Get方式:

[java] view plain
// HttpGet方式請求
public static void requestByHttpGet() throws Exception {
String path = "https://reg.163.com/logins.jsp?id=helloworld&pwd=android";
// 新建HttpGet對象
HttpGet httpGet = new HttpGet(path);
// 獲取HttpClient對象
HttpClient httpClient = new DefaultHttpClient();
// 獲取HttpResponse實例
HttpResponse httpResp = httpClient.execute(httpGet);
// 判斷是夠請求成功
if (httpResp.getStatusLine().getStatusCode() == HTTP_200) {
// 獲取返回的數據
String result = EntityUtils.toString(httpResp.getEntity(), "UTF-8");
Log.i(TAG_HTTPGET, "HttpGet方式請求成功,返回數據如下:");
Log.i(TAG_HTTPGET, result);
} else {
Log.i(TAG_HTTPGET, "HttpGet方式請求失敗");
}
}

Post方式:

[java] view plain
// HttpPost方式請求
public static void requestByHttpPost() throws Exception {
String path = "https://reg.163.com/logins.jsp";
// 新建HttpPost對象
HttpPost httpPost = new HttpPost(path);
// Post參數
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("id", "helloworld"));
params.add(new BasicNameValuePair("pwd", "android"));
// 設置字元集
HttpEntity entity = new UrlEncodedFormEntity(params, HTTP.UTF_8);
// 設置參數實體
httpPost.setEntity(entity);
// 獲取HttpClient對象
HttpClient httpClient = new DefaultHttpClient();
// 獲取HttpResponse實例
HttpResponse httpResp = httpClient.execute(httpPost);
// 判斷是夠請求成功
if (httpResp.getStatusLine().getStatusCode() == HTTP_200) {
// 獲取返回的數據
String result = EntityUtils.toString(httpResp.getEntity(), "UTF-8");
Log.i(TAG_HTTPGET, "HttpPost方式請求成功,返回數據如下:");
Log.i(TAG_HTTPGET, result);
} else {
Log.i(TAG_HTTPGET, "HttpPost方式請求失敗");
}
}

㈥ android post網路數據的請求

public static String HttpPostMethod(String get_url,
List<NameValuePair> params) {
String result = "";
HttpParams basicHttpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(basicHttpParams, 15 * 1000);
HttpConnectionParams.setSoTimeout(basicHttpParams, 15 * 1000);
HttpClient htc = new DefaultHttpClient(basicHttpParams);
HttpResponse httpResponse = null;
try {
HttpPost httpPost = new HttpPost(get_url);
// response = htc.execute(request);
// 設置httpPost請求參數
// 創建參數隊列
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");//json
httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
// httpResponse = new DefaultHttpClient().execute(httpPost);
httpResponse = htc.execute(httpPost);
// System.out.println(httpResponse.getStatusLine().getStatusCode());
Log.d("zh1", get_url+" " + httpResponse.getStatusLine().getStatusCode());
if (httpResponse.getStatusLine().getStatusCode() == 200) {
// 第三步,使用getEntity方法活得返回結果
result = EntityUtils.toString(httpResponse.getEntity(), HTTP.UTF_8);
if(result==null||result.equals("")){
return null;
}
}else{
return null;
}
} catch (ClientProtocolException e) {
e.printStackTrace();
result = null;
} catch (IOException e) {
e.printStackTrace();
result = null;
}
return result;
}

㈦ android網路請求kjhttp怎麼用

1、http協議定義:
WWW是以Internet作為傳輸媒介的一個應用系統,WWW網上基本的傳輸單位是Web網頁。WWW的工作是基於客戶機/伺服器計算模型,由Web瀏覽器和Web伺服器構成,兩者之間採用超文本傳輸協議HTTP進行通信。
HTTP協議時基於TCP/IP協議之上的協議,是Web瀏覽器和Web伺服器之間的應用層的協議,是通用的、無狀態的面向對象的協議。
如果要實現網路互聯我們要思考兩個需要解決的技術問題:
第一:瀏覽器和伺服器是通過什麼來連接的。
第二:這種連接方式是怎麼實現的。
通過Internet去發送到伺服器當中,而Internet內部可以通過三種方式來實現發送信息和數據:
第一種:HTTP協議,也是在工作中最常用的,是建立在TCP/IP基礎上實現的。
第二種:FTP協議
第三種:TCP/IP協議,它也是最底層的協議,其它的方式必須是要通過它,但是要想實現這種協議必須要實現socket編程,這種方法是用來上傳一些比較大的文件,視頻,進行斷點續傳的

㈧ android有幾種請求方式okhttp restful

這個問題有點問題,這並不是三種方式,okhttp只是對網路訪問的一個更高層的封裝,httpURLConnection和httpClient是具體兩種實現訪問的方式。

㈨ 如何使用Android來正確地訪問網路資源

Android應用經常會和伺服器端交互,這就需要手機客戶端發送網路請求,下面介紹四種常用網路請求方式,我這邊是通過Android單元測試來完成這四種方法的,還不清楚Android的單元測試的同學們請看Android開發技巧總結中的Android單元測試的步驟一文。
java.net包中的HttpURLConnection類
Get方式:
[java] view plainprint?
// Get方式請求
public static void requestByGet() throws Exception {
String path = "https://reg.163.com/logins.jsp?id=helloworld&pwd=android";
// 新建一個URL對象
URL url = new URL(path);
// 打開一個HttpURLConnection連接
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
// 設置連接超時時間
urlConn.setConnectTimeout(5 * 1000);
// 開始連接
urlConn.connect();
// 判斷請求是否成功
if (urlConn.getResponseCode() == HTTP_200) {
// 獲取返回的數據
byte[] data = readStream(urlConn.getInputStream());
Log.i(TAG_GET, "Get方式請求成功,返回數據如下:");
Log.i(TAG_GET, new String(data, "UTF-8"));
} else {
Log.i(TAG_GET, "Get方式請求失敗");
}
// 關閉連接
urlConn.disconnect();
}
// Get方式請求
public static void requestByGet() throws Exception {
String path = "https://reg.163.com/logins.jsp?id=helloworld&pwd=android";
// 新建一個URL對象
URL url = new URL(path);
// 打開一個HttpURLConnection連接
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
// 設置連接超時時間
urlConn.setConnectTimeout(5 * 1000);
// 開始連接
urlConn.connect();
// 判斷請求是否成功
if (urlConn.getResponseCode() == HTTP_200) {
// 獲取返回的數據
byte[] data = readStream(urlConn.getInputStream());
Log.i(TAG_GET, "Get方式請求成功,返回數據如下:");
Log.i(TAG_GET, new String(data, "UTF-8"));
} else {
Log.i(TAG_GET, "Get方式請求失敗");
}
// 關閉連接
urlConn.disconnect();
}

Post方式:
[java] view plainprint?
// Post方式請求
public static void requestByPost() throws Throwable {
String path = "https://reg.163.com/logins.jsp";
// 請求的參數轉換為byte數組
String params = "id=" + URLEncoder.encode("helloworld", "UTF-8")
+ "&pwd=" + URLEncoder.encode("android", "UTF-8");
byte[] postData = params.getBytes();
// 新建一個URL對象
URL url = new URL(path);
// 打開一個HttpURLConnection連接
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
// 設置連接超時時間
urlConn.setConnectTimeout(5 * 1000);
// Post請求必須設置允許輸出

㈩ Android網路請求庫【OkHttp4.9.3】基本用法與原理分析

OkHttp是一套處理 HTTP 網路請求的依賴庫,由 Square 公司設計研發並開源,目前可以在 Java 和 Kotlin 中使用。對於 Android App 來說,OkHttp 現在幾乎已經占據了所有的網路請求操作,Retrofit + OkHttp實現網路請求似乎成了一種標配。因此它也是每一個 Android 開發工程師的必備技能,了解其內部實現原理可以更好地進行功能擴展、封裝以及優化。

OkHttp的高效性體現在:

第一步:創建OkHttpClient,創建OkHttpClient有兩種方式:

OkHttpClient提供了豐富的配置方法,例如添加攔截器、指定連接池、設置請求超時等等。

第二步:創建請求

使用Request.Builder() 構建Request實例

第三步:發起網路請求

OkHttp支持同步和非同步兩種請求方式

OkHttp的使用方法非常簡單,三步操作就可以發起一個簡單的同步或非同步請求。我們也可以很輕松地對網路請求進行配置,例如添加請求頭、設置請求方式、設置請求超時等等,這些配置參數會在源碼分析過程中詳細介紹。

現在我們已經學會了三步操作發起網路請求,接下來以這三個步驟為切入點,深入到源碼中學習OkHttp的實現原理,廢話少說馬上開車。

OkHttpClient創建方式有兩種,我們看看兩種方式有什麼區別。

第一種直接使用默認構造函數,內部依然是使用建造者模式

第二種使用建造者模式

兩種方式最終都是調用構造函數OkHttpClient(builder:Builder),由參數builder負責所有的參數配置工作。

當您創建單個OkHttpClient實例並將其用於所有 HTTP 調用時,OkHttp 性能最佳。 這是因為每個OkHttpClient都擁有自己的連接池和線程池,重用連接和線程可減少延遲並節省內存。 相反,為每個請求創建一個客戶端會浪費空閑池上的資源。

Request同樣使用建造者模式來創建,這里貼上部分重要源碼,很簡單就不細說了。

OkHttp發起網路請求分為同步請求和非同步請求兩種方式,我們只分析非同步請求流程,因為只要理解了非同步請求過程,基本上也就明白同步請求是怎麼一回事了。

RealCall是連接應用層與網路層的橋梁,負責處理連接、請求、響應和數據流。

Dispatcher維護著一套非同步任務執行策略,分析策略之前先介紹幾個重要概念:

client.dispatcher.enqueue(AsyncCall(responseCallback)) 執行步驟為:

AsyncCall實現了Runnable介面,因此一旦被線程池中的線程處理就會調用它的run()方法:

話休絮煩,我們開始分析攔截器責任鏈:

責任鏈執行流程:首先獲取當前攔截器interceptor,並且調用interceptor.intercept(next)執行攔截器操作。這里的next表示的是index+1後的責任鏈對象,攔截器的intercept()方法內部會調用next.proceed(request)方法再次進入到責任鏈,由於此時index已經加1,所以處理的是下一個攔截器。

如此循環往復,直到處理完責任鏈上最後一個攔截器為止。

注意除最後一個攔截器CallServerInterceptor不會調用chain.proceed(request)方法之外,其他攔截器都應該至少調用一次chain.proceed(request)方法。

為了驗證上面的結論,我們進入到RetryAndFollowUpInterceptor的intercept()方法一探究竟:

可以看到注釋1處重新進入責任鏈處理下一個攔截器。

有興趣可以自行查看最後一個攔截器CallServerInterceptor源碼,此處只給出本人閱讀源碼後得出的結論:

以上就是攔截器責任鏈的工作流程,我們再通過流程圖仔細感受一下。

分析完攔截器責任鏈,我們繼續分析AsyncCall#run()方法:

我們看到,如果()方法成功獲得服務端返回的數據,則調用responseCallback.onResponse(this@RealCall, response)方法完成非同步回調;如果服務端數據獲取失敗(請求異常),則調用responseCallback.onFailure(this@RealCall, canceledException)方法完成非同步回調

需要注意的是,responseCallback回調是在子線程中完成的,所以如果想把數據顯示到UI上,需要切換回主線程進行UI操作。

OkHttp發起網路請求全過程:

【知識點】OkHttp 原理 8 連問

閱讀全文

與android網路請求方式相關的資料

熱點內容
簡訊刪除助手文件夾 瀏覽:688
java辦公自動化 瀏覽:340
php中超鏈接 瀏覽:253
linux默認路由設置 瀏覽:36
linux如何掛載iso 瀏覽:432
vs程序換文件夾後不能編譯 瀏覽:557
安卓源碼編譯輸入腳本沒反應 瀏覽:47
phpmysql自增 瀏覽:167
把ppt保存為pdf 瀏覽:533
汽車密封件加密配件 瀏覽:887
黑馬程序員15天基礎班 瀏覽:560
java調整格式 瀏覽:521
香港雲伺服器租用價 瀏覽:78
linuxsublime3 瀏覽:560
imac混合硬碟命令 瀏覽:277
沈陽用什麼app租房車 瀏覽:857
00後高中生都用什麼app 瀏覽:238
戴爾塔式伺服器怎麼打開獨立顯卡 瀏覽:807
醫療程序員招聘 瀏覽:598
住宿app可砍價是什麼意思 瀏覽:133