導航:首頁 > 操作系統 > androidhttp原理

androidhttp原理

發布時間:2022-07-19 07:16:04

❶ 怎麼用http協議實現安卓數據

網上介紹android上http通信的文章很多,不過大部分只給出了實現代碼的片段,一些注意事項和如何設計一個合理的類用來處理所有的http請求以及返回結果,一般都不會提及。因此,自己對此做了些總結,給出了我的一個解決方案。

首先,需要明確一下http通信流程,Android目前提供兩種http通信方式,HttpURLConnection和HttpClient,HttpURLConnection多用於發送或接收流式數據,因此比較適合上傳/下載文件,HttpClient相對來講更大更全能,但是速度相對也要慢一點。在此只介紹HttpClient的通信流程:

1.創建HttpClient對象,改對象可以用來多次發送不同的http請求

2.創建HttpPost或HttpGet對象,設置參數,每發送一次http請求,都需要這樣一個對象

3.利用HttpClient的execute方法發送請求並等待結果,該方法會一直阻塞當前線程,直到返回結果或拋出異常。

4.針對結果和異常做相應處理

根據上述流程,發現在設計類的時候,有幾點需要考慮到:

1.HttpClient對象可以重復使用,因此可以作為類的靜態變數

2.HttpPost/HttpGet對象一般無法重復使用(如果你每次請求的參數都差不多,也可以重復使用),因此可以創建一個方法用來初始化,同時設置一些需要上傳到伺服器的資源

3.目前Android不再支持在UI線程中發起Http請求,實際上也不該這么做,因為這樣會阻塞UI線程。因此還需要一個子線程,用來發起Http請求,即執行execute方法

4.不同的請求對應不同的返回結果,對於如何處理返回結果(一般來說都是解析json&更新UI),需要有一定的自由度。

5.最簡單的方法是,每次需要發送http請求時,開一個子線程用於發送請求,子線程中接收到結果或拋出異常時,根據情況給UI線程發送
message,最後在UI線程的handler的handleMessage方法中做結果解析和UI更新。這么寫雖然簡單,但是UI線程和Http請求
的耦合度很高,而且代碼比較散亂、醜陋。

基於上述幾點原因,我設計了一個PostRequest類,用於滿足我的http通信需求。我只用到了Post請求,如果你需要Get請求,也可以改寫成GetRequest

package com.handspeaker.network;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.os.Handler;
import android.util.Log;

/**
*
* 用於封裝&簡化http通信
*
*/
public class PostRequest implements Runnable {

private static final int NO_SERVER_ERROR=1000;
//伺服器地址
public static final String URL = "fill your own url";
//一些請求類型
public final static String ADD = "/add";
public final static String UPDATE = "/update";
public final static String PING = "/ping";
//一些參數
private static int connectionTimeout = 60000;
private static int socketTimeout = 60000;
//類靜態變數
private static HttpClient httpClient=new DefaultHttpClient();
private static ExecutorService executorService=Executors.newCachedThreadPool();
private static Handler handler = new Handler();
//變數
private String strResult;
private HttpPost httpPost;
private HttpResponse httpResponse;
private OnReceiveDataListener onReceiveDataListener;
private int statusCode;

/**
* 構造函數,初始化一些可以重復使用的變數
*/
public PostRequest() {
strResult = null;
httpResponse = null;
httpPost = new HttpPost();
}

/**
* 注冊接收數據監聽器
* @param listener
*/
public void setOnReceiveDataListener(OnReceiveDataListener listener) {
onReceiveDataListener = listener;
}

/**
* 根據不同的請求類型來初始化httppost
*
* @param requestType
* 請求類型
* @param nameValuePairs
* 需要傳遞的參數
*/
public void iniRequest(String requestType, JSONObject jsonObject) {
httpPost.addHeader("Content-Type", "text/json");
httpPost.addHeader("charset", "UTF-8");

httpPost.addHeader("Cache-Control", "no-cache");
HttpParams httpParameters = httpPost.getParams();
HttpConnectionParams.setConnectionTimeout(httpParameters,
connectionTimeout);
HttpConnectionParams.setSoTimeout(httpParameters, socketTimeout);
httpPost.setParams(httpParameters);
try {
httpPost.setURI(new URI(URL + requestType));
httpPost.setEntity(new StringEntity(jsonObject.toString(),
HTTP.UTF_8));
} catch (URISyntaxException e1) {
e1.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}

/**
* 新開一個線程發送http請求
*/
public void execute() {
executorService.execute(this);
}

/**
* 檢測網路狀況
*
* @return true is available else false
*/
public static boolean checkNetState(Activity activity) {
ConnectivityManager connManager = (ConnectivityManager) activity
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connManager.getActiveNetworkInfo() != null) {
return connManager.getActiveNetworkInfo().isAvailable();
}
return false;
}

/**
* 發送http請求的具體執行代碼
*/
@Override
public void run() {
httpResponse = null;
try {
httpResponse = httpClient.execute(httpPost);
strResult = EntityUtils.toString(httpResponse.getEntity());
} catch (ClientProtocolException e1) {
strResult = null;
e1.printStackTrace();
} catch (IOException e1) {
strResult = null;
e1.printStackTrace();
} finally {
if (httpResponse != null) {
statusCode = httpResponse.getStatusLine().getStatusCode();
}
else
{
statusCode=NO_SERVER_ERROR;
}
if(onReceiveDataListener!=null)
{
//將注冊的監聽器的onReceiveData方法加入到消息隊列中去執行
handler.post(new Runnable() {
@Override
public void run() {
onReceiveDataListener.onReceiveData(strResult, statusCode);
}
});
}
}
}

/**
* 用於接收並處理http請求結果的監聽器
*
*/
public interface OnReceiveDataListener {
/**
* the callback function for receiving the result data
* from post request, and further processing will be done here
* @param strResult the result in string style.
* @param StatusCode the status of the post
*/
public abstract void onReceiveData(String strResult,int StatusCode);
}

}

代碼使用了觀察者模式,任何需要接收http請求結果的類,都要實現OnReceiveDataListener介面的抽象方法,同時PostRequest實例調用setOnReceiveDataListener方法,注冊該監聽器。完整調用步驟如下:

1.創建PostRequest對象,實現onReceiveData介面,編寫自己的onReceiveData方法

2.注冊監聽器

3.調用PostRequest的iniRequest方法,初始化本次request

4.調用PostRequest的execute方法

可能的改進:

1.如果需要多個觀察者,可以把只能注冊單個監聽器改為可以注冊多個監聽器,維護一個監聽器List。

2.如果需求比較簡單,並希望調用流程更簡潔,iniRequest和execute可以合並

❷ 我想了解android http請求 同步與非同步的區別

給你舉一個例子,點擊按鈕執行HTTP請求然後跳轉下一頁。
同步:發送http請求→獲取返回結果→分析結果→跳轉下一頁
非同步:發送http請求→跳轉下一頁(不需要等待請求結果,對結果的處理在另一個線程中)

❸ android的自帶的httpClient 怎麼上傳文件

在Android開發中,Android SDK附帶了Apache的HttpClient,它是一個完善的客戶端。它提供了對HTTP協議的全面支持,可以使用HttpClient的對象來執行HTTP GET和HTTP POST調用。

HTTP工作原理:

1.客戶端(一般是指瀏覽器,這里是指自己寫的程序)與伺服器建立連接

2.建立連接後,客戶端向伺服器發送請求

3.伺服器接收到請求後,向客戶端發送響應信息

4.客戶端與伺服器斷開連接


HttpClient的一般使用步驟:

1.使用DefaultHttpClient類實例化HttpClient對象

2.創建HttpGet或HttpPost對象,將要請求的URL通過構造方法傳入HttpGet或HttpPost對象。

3.調用execute方法發送HTTP GET或HTTP POST請求,並返回HttpResponse對象。

4.通過HttpResponse介面的getEntity方法返回響應信息,並進行相應的處理。

最後記得要在AndroidManifest.xml文件添加網路許可權

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


附件中包含了一個拍照上傳的源代碼


❹ android https和http有什麼區別

https是加密的,用雙重密鑰加密。
①首先製作一個證書,保存RSA密鑰,客戶端和服務端分別保存兩份密鑰;
②然後每次請求內容時隨機生成一個AES密鑰,客戶端請求的內容和服務端返回的內容都使用這個AES密鑰加密,保證在傳輸過程中即使被黑客抓包他也看不到原文,只能看到密文;
③AES密鑰本身(一般是6位十六進制數)被第一步的RSA密鑰加密,由於Android端和伺服器端保存了rsa的公鑰和私鑰,所以可以知道本次傳輸的AES密鑰,進而解析內容;
以上就是https加密傳輸的大致過程,而http傳輸則沒有加密過程,全部明文傳輸,一旦被抓包內容也就泄露了。

❺ Android Http連接和TCP連接的區別

Http是應用層協議,TCP是網路層協議,應用層在TCP/IP四層架構中位於TCP的上一層。

建立Http連接在實現時有以下兩種方式:
1、[java] view plain
DefaultHttpClient http = new DefaultHttpClient();
HttpGet method = new HttpGet(url);
HttpResponse response =http.execute(method);
2、[java] view plain
URL url = new URL(uri);
HttpURLConnection connection = (HttpURLConnection)
url.openConnection();
connection.connect();

而TCP連接在實現時要藉助Socket(套接字 IP+埠號)
[java] view plain
Socket s = new Socket("localhost", 12345);

區別從這兩個連接的實現方式就可以看出來,HTTP連接需要指明資源的URL,發出請求的應用不知道伺服器的IP,雖然域名伺服器也是要把域名解析成IP地址,但不屬於應用所關心的范疇,是網路層應該完成的工作。所以Http連接屬於無狀態的短連接,若再請求其他數據,需要再重新建立連接。客戶端向伺服器發送請求後,伺服器才知道客戶端的存在。
TCP連接實現時需要指明IP地址和埠號,就可以跟目的主機通過三次握手建立聯系,該連接一直保持直到某一方提出取消連接,通過四次握手關閉連接。Socket支持TCP/UDP協議,如果使用TCP協議,那麼socket連接就是TCP連接。論文提到的應用場景是手機與雲端的伺服器建立聯系,因為要保持連接並指定連接的建立時間,所以在這種場景下使用TCP連接最合適。3G網路不支持端到端建立TCP連接,因為它是client-server模式,所以需要通過雲端伺服器的輔助來實現手機的端到端通信。

❻ android怎麼實現HTTP長連接

Push在Android平台上長連接的實現:
既然我們知道我們移動端要和Internet進行通信,必須通過運營商的網關,所以,為了不讓NAT映射表失效,我們需要定時向Internet發送數據,因為只是為了不然NAT映射表失效,所以只需發送長度為0的數據即可。

這時候就要用到定時器,在android系統上,定時器通常有一下兩種:
1.java.util.Timer
2.android.app.AlarmManager

分析:
Timer:可以按照計劃或者時間周期來執行相關的任務。但是Timer需要用WakeLock來讓CPU保持喚醒狀態,才能保證任務的執行,這樣子會消耗大量流量;當CPU處於休眠的時候,就不能喚醒執行任務,所以應用於移動端明顯是不合適。

AlarmManager:AlarmManager類是屬於android系統封裝好來管理RTC模塊的管理類。這里就涉及到RTC模塊,要更好地了解兩者的區別,就要明白兩者真正的區別。
RTC(Real- Time Clock)實時鬧鍾在一個嵌入式系統中,通常採用RTC 來提供可靠的系統時間,包括時分秒和年月日等;而且要求在系統處於關機狀態下它也能夠正常工作(通常採用後備電池供電),它的外圍也不需要太多的輔助電路,典型的就是只需要一個高精度的32.768KHz 晶體和電阻電容等。(如果對這方面感興趣,可以自己查閱相關資料,這里就說個大概)
好了,回來正題。所以,AlarmManager又稱全局定時鬧鍾。這意味著,當我用使用AlarmManager來定時執行任務,CPU可以正常地休眠,只有在執行任務是,才喚醒CPU,這個過程是很短時間的。
下面簡單來說明其使用:
1.類似於Timer功能:
//獲得鬧鍾管理器
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
//設置任務執行計劃
am.setRepeating(AlarmManager.ELAPSED_REALTIME, firstTime, 5*1000, sender);//從firstTime才開始執行,每隔5秒再執行

2.實現全局定時功能:
//獲得鬧鍾管理器
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
//設置任務執行計劃
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, 5*1000, sender);//從firstTime才開始執行,每隔5秒再執行

總結:在android客戶端使用Push推送時,應該使用AlarmManager來實現心跳功能,使其真正實現長連接。

在伺服器端的實現:
在伺服器端,可以使用很多語言來實現,如C/C++,java,Erlang等等,如我們國內比較好的極光推送(C開發),openfire(java開發)等等。
最近我看了極光推送的介紹和原理,下面我就說說他們是遇到什麼難題,然後使用什麼技術或者方案來解決呢。

當有大量的手機終端需要與伺服器維持長連接時,對伺服器的設計會是一個很大的挑戰。

假設一台伺服器維護10萬個長連接,當有1000萬用戶量時,需要有多達100台的伺服器來維護這些用戶的長連接,這里還不算用於做備份的伺服器,這將會是一個巨大的成本問題。那就需要我們盡可能提高單台伺服器接入用戶的量,也就是業界已經討論很久了的 C10K 問題。
C2000K

針對這個問題,他們專門成立了一個項目,命名為C2000K,顧名思義,他們的目標是單機維持200萬個長連接。最終他們採用了多消息循環、非同步非阻塞的模型,在一台雙核、24G內存的伺服器上,實現峰值維持超過300萬個長連接。

最後總結:
因為我最近用java在做一個PC、伺服器、android的即時通訊系統(說白了就是模仿QQ,後面希望有不同的功能)。我的原則是用別人的原理,自己來實現,這樣才更好深入了解一些框架。所以,估計難點是在通訊開發和伺服器上的開發,必須深刻了解多消息循環、非同步非阻塞的模型。之後我會發表關於這方面的實現。
在現在的android平台上,已經不是android單機的世界了(我不是說做單機游戲沒有前途)。現在都是依靠發展蓬勃的互聯網來支撐整個IT體系,所以,要成為一個android應用開發高手,必須朝著android、硬體、雲服務這一體系來發展。

❼ android http請求 如何實現斷網後來網,自動載入。

創建一個監聽網路狀態的線程,每隔10秒鍾檢測一次網路狀態
當檢測到網路狀態後由未連接轉為已連接的時候,重新開始載入數據並重新設置View的值
比如
while(true){

if(networkConneted && networkUnconnect){

dataThread().start();

networkUnnected = false;

} else {

if( ! networkConneted()){

networkUnconnect = false;
}
}

Thread.sleep(10);

}

❽ android在子線程開啟一個發送http請求,為什麼最後還要通過回調方法處理網路返回的結果為什

這是一種比較常見的做法,主要是為了架構以及穩定性。
首先,一般大型軟體開發時,負責網路通信的,和對數據做處理的,往往是兩個不同的模塊
這樣通過回調的方式,使代碼的耦合性降低,更易於分塊。
其次,為了避免在處理數據時佔用過多時間,引起網路數據的丟失及擁堵。

❾ 怎樣實現android http-post方法實例說明

代碼如下:

package com.hl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
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 android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class SimplePOST extends Activity {
private TextView show;
private EditText txt;
private Button btn;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
show = (TextView)findViewById(R.id.show);
txt = (EditText)findViewById(R.id.txt);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
dopost(txt.getText().toString());

}
});
}

private void dopost(String val){
//封裝數據
Map<String, String> parmas = new HashMap<String, String>();
parmas.put("name", val);

DefaultHttpClient client = new DefaultHttpClient();//http客戶端
HttpPost httpPost = new HttpPost("http://mhycoe.com/test/post.php");

ArrayList<BasicNameValuePair> pairs = new ArrayList<BasicNameValuePair>();
if(parmas != null){
Set<String> keys = parmas.keySet();
for(Iterator<String> i = keys.iterator(); i.hasNext();) {
String key = (String)i.next();
pairs.add(new BasicNameValuePair(key, parmas.get(key)));
}
}

try {
UrlEncodedFormEntity p_entity = new UrlEncodedFormEntity(pairs, "utf-8");
/*
* 將POST數據放入HTTP請求
*/
httpPost.setEntity(p_entity);
/*
* 發出實際的HTTP POST請求
*/
HttpResponse response = client.execute(httpPost);
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
String returnConnection = convertStreamToString(content);
show.setText(returnConnection);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}

private String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}

❿ android怎麼理解http協議

超文本傳輸協議(HTTP,HyperText Transfer Protocol)是互聯網上應用最為廣泛的一種網路協議。所有的WWW文件都必須遵守這個標准。設計HTTP最初的目的是為了提供一種發布和接收HTML頁面的方法。
HTTP是一個客戶端和伺服器端請求和應答的標准(TCP)。客戶端是終端用戶,伺服器端是網站。通過使用Web瀏覽器、網路爬蟲或者其它的工具,客戶端發起一個到伺服器上指定埠(默認埠為80)的HTTP請求。(我們稱這個客戶端)叫用戶代理(user agent)。應答的伺服器上存儲著(一些)資源,比如HTML文件和圖像。(我們稱)這個應答伺服器為源伺服器(origin server)。在用戶代理和源伺服器中間可能存在 http和其他幾種網路協議[1]多個中間層,比如代理,網關,或者隧道(tunnels)。盡管TCP/IP協議是互聯網上最流行的應用,HTTP協議並沒有規定必須使用它和(基於)它支持的層。 事實上,HTTP可以在任何其他互聯網協議上,或者在其他網路上實現。HTTP只假定(其下層協議提供)可靠的傳輸,任何能夠提供這種保證的協議都可以被其使用。通常,由HTTP客戶端發起一個請求,建立一個到伺服器指定埠(默認是80埠)的TCP連接。HTTP伺服器則在那個埠監聽客戶端發送過來的請求。一旦收到請求,伺服器(向客戶端)發回一個狀態行,比如"HTTP/1.1 200 OK",和(響應的)消息,消息的消息體可能是請求的文件、錯誤消息、或者其它一些信息。 HTTP協議的網頁HTTP使用TCP而不是UDP的原因在於(打開一個)一個網頁必須傳送很多數據,而TCP協議提供傳輸控制,按順序組織數據,和錯誤糾正。通過HTTP或者HTTPS協議請求的資源由統一資源標示符(Uniform Resource Identifiers)(或者,更准確一些,URLs)來標識。

閱讀全文

與androidhttp原理相關的資料

熱點內容
好興動app還款怎麼登錄不上去了 瀏覽:663
鄭州雲伺服器託管 瀏覽:720
伺服器地址跟蹤 瀏覽:978
免費google雲伺服器 瀏覽:516
摘譯和編譯的英文 瀏覽:359
熱泵壓縮機選型 瀏覽:121
op手機微信加密如何解除 瀏覽:386
如何在王牌戰爭找到高爆率伺服器 瀏覽:13
江浙小學語文輔導課用什麼APP 瀏覽:99
新夢幻大陸伺服器地址 瀏覽:241
網吧伺服器怎麼更換壁紙 瀏覽:530
linux命令方法 瀏覽:332
linux下載freetype 瀏覽:123
程序員入駐平台 瀏覽:327
程序員大戰外掛 瀏覽:745
html實例教程pdf 瀏覽:157
linux命令開放所有許可權 瀏覽:575
30歲能學會編程 瀏覽:737
小火箭的伺服器是什麼 瀏覽:967
cad查信息命令 瀏覽:402