標籤:
上次我們講到了使用URLConnection的網路編程,URLConnection已經可以非常方便地與指定網站交換資訊,URLConnection下還有一個子類:HttpURLConnection。
HttpURLConnection在URLConnection的基礎上進行改進,增加了一些用於操作HTTP資源的便捷方法。
setRequestMethod(String):設定發送請求的方法 getResponseCode():擷取伺服器的響應代碼getResponseMessage():擷取伺服器的響應訊息
a)get請求的代碼:
conn=(HttpURLConnection)url.openConnection();//注意要大寫conn.setRequestMethod("GET");conn.setConnectTimeout(8000);//連線逾時的毫秒數conn.setReadTimeout(8000);//讀取逾時的毫秒數
b)post請求的代碼
conn=(HttpURLConnection)url.openConnection();//注意要大寫conn.setRequestMethod("POST");
c)關閉串連
if(conn!=null)conn.disconnect();
注意需要的許可權:
使用URLConnection的步驟:
①把網址填充成一個URL對象
URL url = new URL(String spec);
②擷取用戶端與伺服器的連線物件,此時還沒有串連
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
③對連線物件初始化
conn.setRequestMethod("GET"); //佈建要求方式,注意大寫conn.setConnectTimeout(5000);//設定連線逾時時間conn.setReadTimeout(5000);//設定讀取逾時時間
④發送請求,建立串連
conn.connect();
⑤擷取伺服器響應中的流
InputStream is = conn.getInputStream();
⑥對流中的資料進行操作(如字串、圖片)
這裡看一個使用HttpURLConnection下載圖片的樣本(只不過裡面用了點小小的技巧,第一次載入網狀圖片,就將次圖片緩衝起來,以後載入就直接從緩衝裡取,不用訪問網路):
效果:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.briup.httpurlconnection.MainActivity"> <Button android:onClick="onClick" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="載入圖片"/> <ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="wrap_content"/></LinearLayout>
MainActivity.java
package com.example.httpurlconnection;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.ImageView;import android.widget.Toast;public class MainActivity extends Activity { private ImageView iv; //網狀圖片的地址 private String path = "https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png"; public static final int SUCCESS = 0X1; //成功載入的標誌 public static final int FAIL = 0X0; //失敗載入的標誌 private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what) { case SUCCESS: iv.setImageBitmap((Bitmap) msg.obj); break; case FAIL: Toast.makeText(MainActivity.this, "請求失敗", Toast.LENGTH_LONG).show(); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (ImageView) findViewById(R.id.iv); } public void onClick(View view) { final File mFile = new File(getCacheDir(),"a2.jpg"); //判斷是否有緩衝 if (mFile.exists()) {//有緩衝 Toast.makeText(this,"使用緩衝",Toast.LENGTH_LONG).show(); Bitmap bitmap = BitmapFactory.decodeFile(mFile.getAbsolutePath()); iv.setImageBitmap(bitmap); }else { //沒有緩衝,請求網路 new Thread(){ @Override public void run() { try { Toast.makeText(MainActivity.this,"沒有緩衝",Toast.LENGTH_LONG).show(); //1.把網址填充成一個URL對象 URL url = new URL(path); //2.擷取用戶端與伺服器的連線物件,此時還沒有串連 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //3.對連線物件初始化 conn.setRequestMethod("GET"); //佈建要求方式,注意大寫 conn.setConnectTimeout(5000);//設定連線逾時時間 conn.setReadTimeout(5000);//設定讀取逾時時間 //4.發送請求,建立串連 conn.connect(); //返回碼為200時表示請求成功 if (conn.getResponseCode() == 200) { //擷取伺服器響應中的流 InputStream is = conn.getInputStream(); //把伺服器的流中的資料寫入本地檔案,緩衝起來 FileOutputStream fos = new FileOutputStream(mFile); byte[] b = new byte[1024]; int len = 0; while ((len = is.read(b)) != -1) { fos.write(b,0,len); } fos.flush(); fos.close(); //此時流中已經沒有了資料 //從檔案中擷取圖片 Bitmap bitmap = BitmapFactory.decodeFile(mFile.getAbsolutePath()); Message msg = Message.obtain(); //載入成功 msg.what = SUCCESS; msg.obj = bitmap; mHandler.sendMessage(msg); }else { Message msg = Message.obtain(); //載入失敗 msg.what = FAIL; mHandler.sendMessage(msg); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }.start(); } }}
HttpURLConnection源碼:http://download.csdn.net
——HttpClient
android5.0之前.常用 android5.0之後,被HttpURLConnecetion替代 android6.0完全被捨棄 HttpClient是Apache提供的Http網路提供者。完成的功能和HttpURLConnection幾乎一模一樣的效果,但兩者的用法有很大的差別。 在一般情況下,如果只是需要向Web網站的某個簡單頁面提交請求並擷取伺服器響應,完全可以使用前面介紹的HttpURLConnection來完成,但是在絕大部分情況下,Web網站網頁沒這麼簡單,這些頁面並不是通過一個簡單的URL就可訪問的,可能需要使用者登入而且具有相應的許可權才可訪問該頁面,在這種情況下,就需要涉及Session,Cookie的處理了。 HttpClient是一個簡單的HTTP用戶端,並不是瀏覽器。可以用於發送HTTP請求,接受HTTP響應,但不會快取服務器的響應,不能執行HTML頁面中嵌入的javascript代碼,也不會對頁面進行任何解析,處理。 HttpClient會自動維護與伺服器之間的Session狀態,但是前提是使用同一個HttpClient對象發送請求。
使用HttpClient的步驟:HttpClient是一個介面。
a)建立HttpClient對象:new DefaultHttpClient(); b)如果需要發送GET請求,建立HttpGet對象,並指定地址。 如果需要發送Post請求,建立HttpPost對象, c)如果需要發送請求參數,可調用HttpGet,HttpPost共同的setParams(HttpParams)方法來添加請求參數,對於HttpPost對象而言,也可調用setEntity(HttpEntity)方法佈建要求參數。 使用HttpEntity下的UrlEncodedFormEntitiy對象傳入一個放入BasicNameValuePair的集合中提交的資料。 如:HttpPost post=new HttpPost("");List<NameValuePair> list=new ArrayList<>();list.add(new BasicNameValuePair("name",name));list.add(new BasicNameValuePair("pwd", pwd));post.setEntity(new UrlEncodedFormEntity(list,"UTF-8")); d)調用HttpClient對象execute(HttpUriRequest)發送請求,執行該方法返回一個HttpResponse; e)調用HttpResponse的getstatusLine().getStatesCode()方法可以擷取響應的狀態代碼,如果是200就代碼是成功的狀態。調用HttpResponse的getEntity()方法擷取HttpEntity對象,該對象封裝了伺服器的響應內容。程式可通過該對象擷取伺服器的響應內容。然後再用EntityUtils.toString(HttpEntity,"編碼方式")將其轉成為字串。
——HttpClient返回不同資料的解析方式
a)返回普通的text資料
b)返回html資料
c)返回xml資料
xml的解析可以採用sax,dom,dom4j,pull
d)返回JSON資料(在上次的文章JSON解析中提到過)
注意:
1.中文亂碼問題:三種方式
String n=URLEncoder.encode(“張三”, “UTF-8”);
String n=EncodingUtils.getString(“張三”.getBytes(),”UTF-8”);該方式已經過時了
con.setRequestProperty(“Charset”, “UTF-8”);
2.HttpClient類把編譯版本換到6.0以下應該就能用了,
在6.0的時候刪除httpclient了,
在5.1他就過時了,官方不推薦使用了.
android開發筆記之網路編程—使用HTTP進行網路編程