前言:通過網(wǎng)上查詢Android網(wǎng)絡通信機制,大部分都是介紹這三種课竣。因此嘉赎,自己通過代碼來實現(xiàn)網(wǎng)絡通信。
首先先通過該網(wǎng)址 http://www.w3school.com.cn/tags/html_ref_httpmethods.asp 了解http中最常用的get和post請求區(qū)別公条。
一、標準的java接口(java.NET)
HttpURLConnection
HttpURLconnection是基于http協(xié)議的迂曲,支持get,post路捧,put关霸,delete等各種請求方式杰扫,最常用的就是get和post队寇,下面針對這兩種請求方式進行講解。
HttpURLconnection是同步的請求佳遣,所以必須放在子線程中,下面以登錄功能凡伊,來進行分析。(親測)
private String getUrl = "網(wǎng)址/login.shtml?loginName=xxxxx&password=xxxxx";
private String headUrl = "網(wǎng)址/login.shtml";
MyHttpURLConnection( ) {
new Thread(new Runnable() {
@Override
public void run( ) {
try {
URL url = new URL(getUrl);
//得到connection對象窗声。
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//設置請求方式
connection.setRequestMethod("GET");
connection.setConnectTimeout(3000);//連接的超時時間
//連接
connection.connect();
//得到響應碼
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
//得到響應流 connection.getInputStream()只是得到一個流對象,并不是數(shù)據(jù)笨觅,從這個流對象中只能讀取一次數(shù)據(jù),第二次讀取時將會得到空數(shù)據(jù)
InputStream inputStream1 = connection.getInputStream();
//將響應流轉(zhuǎn)換成字符串
String result1 = stream2String(inputStream1);//將流轉(zhuǎn)換為字符串见剩。
Log.d("getHttpURLConnection","result=============" + result1);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run( ) {
try {
URL url = new URL(getUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");//設置請求方式為POST
connection.setConnectTimeout(3000);//連接的超時時間
connection.setDoOutput(true);//允許寫出
connection.setDoInput(true);//允許讀入
connection.setUseCaches(false);//不使用緩存
connection.connect();//連接
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
String result = stream2String(inputStream);//將流轉(zhuǎn)換為字符串。
Log.d("postHttpURLConnection1","result=============" + result);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run( ) {
try {
URL url = new URL(headUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.connect();
String body = "loginName=xxxx&password=xxxx";
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(),
"UTF-8"));
writer.write(body);
writer.close();
//post Json數(shù)據(jù)
// connection.setRequestProperty("Content-Type", "application/json;
// charset=utf-8");//設置參數(shù)類型是json格式
// connection.connect();
// String body = "{userName:xxxx,password:xxxx}";
// BufferedWriter writer = new BufferedWriter(new OutputStreamWriter
// (connection.getOutputStream(), "UTF-8"));
// writer.write(body);
// writer.close();
//post上傳文件
// connection.setRequestProperty("Content-Type", "file/*");//設置數(shù)據(jù)類型
// connection.connect();
// OutputStream outputStream = connection.getOutputStream();
// FileInputStream fileInputStream = new FileInputStream("file");//把文件封裝成一個流
// int length = -1;
// byte[] bytes = new byte[1024];
// while ((length = fileInputStream.read(bytes)) != -1){
// outputStream.write(bytes,0,length);//寫的具體操作
// }
// fileInputStream.close();
// outputStream.close();
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
String result = stream2String(inputStream);//將流轉(zhuǎn)換為字符串固翰。
Log.d("postHttpURLConnection2","result=============" + result);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
/**
* 將get獲取的字節(jié)流轉(zhuǎn)換為字符串
* @param is
* @return
* @throws IOException
*/
private String stream2String(InputStream is) throws IOException {
if (is != null) {// ByteArrayOutputStream好處:邊讀,邊緩沖數(shù)據(jù)// 可以捕獲內(nèi)存緩沖區(qū)的數(shù)據(jù)骂际,轉(zhuǎn)換成字節(jié)數(shù)組
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int temp = -1;
while ((temp = is.read(buffer)) != -1) {
baos.write(buffer,0,temp);
}
is.close();
baos.close();
return baos.toString();
}
return null;
}
以上是簡單的HttpURLConnection數(shù)據(jù)請求,得到的結果是一樣的歉铝,通過以上代碼可以清晰的看得出盈简,post和get請求數(shù)據(jù)的基本差異太示,以及它們通過網(wǎng)址的不同請求。
以下是http://www.w3school.com.cn/tags/html_ref_httpmethods.asp中的關于post和get請求區(qū)別列表
圖上標記為目前我所能看到和實現(xiàn)的类缤。
socket(這個比較特殊,下次有空詳細介紹)
二餐弱、Apache接口(org.apache.http)
HttpClient
private String getUrl = "網(wǎng)址/login.shtml?loginName=xxx&password=xxx";
private String headUrl = "網(wǎng)址/login.shtml";
private final BasicCookieStore cookieStore = new BasicCookieStore();
private HttpResponse getResp;
private HttpResponse postResp;
private HttpClient mHttpClient;
public MyHttpClient( ) {
new Thread(new Runnable() {//get請求數(shù)據(jù)
@Override
public void run( ) {
mHttpClient = new DefaultHttpClient();
// 保持和服務器登錄狀態(tài)一直是登錄著的,必不可少設置全局唯一的Cookie(不了解這步的意圖岸裙,加不加都可get數(shù)據(jù))
((AbstractHttpClient) mHttpClient).setCookieStore(cookieStore);
HttpGet httpGet = new HttpGet(getUrl);
httpGet.addHeader("contentType","application/json");
try {
getResp = mHttpClient.execute(httpGet);
if (getResp.getStatusLine().getStatusCode() == 200) {
String result = EntityUtils.toString(getResp.getEntity());
Log.i(TAG,"get請求結果: " + result);
} else {
Log.i(TAG,"get請求結果: error");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {//post請求數(shù)據(jù)
@Override
public void run( ) {
mHttpClient = new DefaultHttpClient();
// 保持和服務器登錄狀態(tài)一直是登錄著的速缆,必不可少設置全局唯一的Cookie
((AbstractHttpClient) mHttpClient).setCookieStore(cookieStore);
HttpPost httpPost = new HttpPost(getUrl);
httpPost.addHeader("contentType","application/json");
try {
postResp = mHttpClient.execute(httpPost);
if (postResp.getStatusLine().getStatusCode() == 200) {
String result = EntityUtils.toString(postResp.getEntity());
Log.i(TAG,"post請求結果: " + result);
} else {
Log.i(TAG,"post請求結果: error");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {//post請求數(shù)據(jù)
@Override
public void run( ) {
//創(chuàng)建客戶端對象
mHttpClient = new DefaultHttpClient();
//創(chuàng)建post請求對象
HttpPost httpPost = new HttpPost(headUrl);
//封裝form表單提交的數(shù)據(jù)
BasicNameValuePair basicNameValuePair1 = new BasicNameValuePair("loginName","xxx");
BasicNameValuePair basicNameValuePair2 = new BasicNameValuePair("password","xxx");
List<BasicNameValuePair> parameters = new ArrayList<>();
//把BasicNameValuePair放入集合中
parameters.add(basicNameValuePair1);
parameters.add(basicNameValuePair2);
try {
//要提交的數(shù)據(jù)都已經(jīng)在集合中了,把集合傳給實體對象
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters,"utf-8");
//設置post請求對象的實體剧董,其實就是把要提交的數(shù)據(jù)封裝至post請求的輸出流中
httpPost.setEntity(entity);
//3.使用客戶端發(fā)送post請求
postResp = mHttpClient.execute(httpPost);
if (postResp.getStatusLine().getStatusCode() == 200) {
InputStream result = postResp.getEntity().getContent();
Log.i(TAG,"post請求結果: " + getTextFromStream(result));
} else {
Log.i(TAG,"post請求結果: error");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start()
}
/**
* 字節(jié)流轉(zhuǎn)換為字符串
* @param result
* @return
*/
private String getTextFromStream(InputStream result) {
byte[] b = new byte[1024];
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
while ((len = result.read(b)) != -1) {
bos.write(b,0,len);
}
String text = new String(bos.toByteArray());
bos.close();
return text;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
以上是HttpClient的get和post請求數(shù)據(jù)破停,簡單的三種數(shù)據(jù)請求翅楼,得到的結果相同真慢,在httpClient中post和get請求數(shù)據(jù)除了HttpPost 和httpGet的對象不同,其余的沒有什么差異黑界,不過也能實現(xiàn)上圖中get和post的區(qū)別表中的特性管嬉。
三朗鸠、Android.net網(wǎng)絡接口
對于android.net網(wǎng)絡接口本人不了解,但從網(wǎng)上查詢了解了一下之后烛占,知道這就是一個api接口,android自帶的接口,常常使用此包下的類進行Android特有的網(wǎng)絡編程德迹,如:訪問WiFi,訪問Android聯(lián)網(wǎng)信息项栏,郵件等功能。這個我用的比較少沼沈,一般用的都是別人寫好的。
private Context mContext;
AndroidNet(Context context) {
this.mContext = context;
}
/**
* 確定您是否連入了互聯(lián)網(wǎng)
* 如果您未連入互聯(lián)網(wǎng)列另,則無需安排基于互聯(lián)網(wǎng)資源的更新芽腾。 下面這段代碼展示了如何利用 ConnectivityManager 查詢活動網(wǎng)絡并確定其是否連入了互聯(lián)網(wǎng)页衙。
* @return true 已連接
*/
private boolean IsNoConnected( ) {
ConnectivityManager cm =
(ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
//是否是wifi
//boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
return isConnected;
}
這個https://developer.android.google.cn/reference/android/net/wifi/package-summary
網(wǎng)址是官網(wǎng)提供的,里面有對android.net的詳解
以上是我對于通信機制類型的簡單了解店乐,若有補充不到或理解有誤的地方艰躺,望賜教。