1. 肯定圖片的網址html
2. 發送http請求java
URL url = new URL(address); // 獲取客戶端和服務器的鏈接對象,此時尚未創建鏈接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 設置請求方式,注意必須大寫 conn.setRequestMethod("GET"); // 設置鏈接和讀取超時 conn.setConnectTimeout(5000); conn.setReadTimeout(5000); // 發送請求,與服務器創建鏈接 conn.connect(); // 若是響應碼爲200,說明請求成功 if(conn.getResponseCode() == 200){ }
3. 服務器的圖片是以流的形式返回給瀏覽器的android
InputStream is = conn.getInputStream(); // 拿到服務器返回的輸入流 Bitmap bm = BitmapFactory.decodeStream(is);// 把流裏的數據讀取出來,並構形成位圖對象
4. 把位圖對象顯示至ImageView數組
ImageView iv = (ImageView) findViewById(R.id.iv);
iv.setImageBitmap(bm);
須要添加權限瀏覽器
<uses-permission android:name="android.permission.INTERNET"/>
在Android中,主線程被阻塞會致使UI中止刷新,用戶體驗將很是差,若主線程阻塞時間過長,就會拋出ANR(Application Not Responding,即應用無響應)異常。所以任何耗時操做都不該該在主線程進行,不然可能使主線程阻塞。由於網絡請求屬於耗時操做,若是網速很慢,線程會被阻塞,因此網絡請求的代碼不能寫在主線程中。緩存
主線程又稱UI線程,由於只有在主線程中才能刷新UI。若是須要在子線程中刷新UI,須要藉助Handler的消息傳遞機制服務器
主線程建立時,系統會爲主線程建立一個Looper(ActivityThread中的main方法中依次調用Looper.prepareMainLooper(),Looper.loop()),而Looper對象在初始化時會建立一個與之關聯的MessageQueue網絡
若是是子線程的話,須要咱們本身在子線程調用Looper.prepare()來爲子線程建立一個Looper(Looper對象在初始化時仍會建立一個與之關聯的MessageQueue),而後再調用Looper.loop()來啓動這個Looperapp
Looper.loop()使用一個死循環不斷的取出MessageQueue中的Message,而後將Message分發給曾經發送它的Handler進行處理(若是MessageQueue中沒有Message,loop()方法會暫時阻塞,實際上Android系統的UI線程始終處於loop死循環中,一旦退出這個消息循環,App也就退出了)ide
Handler收到Message後會回調它的handleMessage()來處理這條Message。若是這個handleMessage()方法運行在主線程中,就能夠刷新UI
/** * 調用默認的構造器new一個Handler會將它與所在的線程關聯起來 * 若是Handler關聯的線程沒有Looper,就會拋出以下異常 * java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() * 這裏是在主線程中直接new一個Handler,不會拋異常,且handleMessage()能夠刷新UI */ android.os.Handler handler = new android.os.Handler(){ public void handleMessage(Message msg) { } };
在子線程中向Handler所在線程的MessageQueue裏發送Message
Message msg = handler.obtainMessage();// 這樣建立Message對象比直接new更節省空間 msg.obj = bm; // obj字段能夠賦值任何對象,用來攜帶數據 msg.what = 1; // what字段至關於一個標籤,用來區分出不一樣的Message,從而進行不一樣的處理 handler.sendMessage(msg);
經過switch語句區分不一樣的Message
public void handleMessage(android.os.Message msg) { switch (msg.what) { // 若是是1,說明是請求成功的Message case 1: ImageView iv = (ImageView) findViewById(R.id.iv); Bitmap bm = (Bitmap) msg.obj; iv.setImageBitmap(bm); break; case 2: Toast.makeText(MainActivity.this, "請求失敗", 0).show(); break; } }
讀取服務器返回的流裏的數據,把數據寫到本地文件緩存起來
InputStream is = conn.getInputStream(); FileOutputStream fos = new FileOutputStream(file); byte[] b = new byte[1024]; int len = 0; while((len = is.read(b)) != -1){ fos.write(b, 0, len); } fos.close();
讀取緩存的數據,並構形成位圖對象
Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath());
每次發送請求前檢測一下在緩存中是否存在同名圖片,若是存在,則讀取緩存
發送GET請求
URL url = new URL(path); //獲取鏈接對象,此時還未創建鏈接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //設置鏈接屬性 conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); // 能夠不寫conn.connect(); // 若是不寫conn.connect();,getResponseCode()會先創建鏈接,而後得到響應碼 if(conn.getResponseCode() == 200){ }
獲取服務器返回的流,從流中把html源碼讀取出來
InputStream is = conn.getInputStream(); byte[] b = new byte[1024]; int len = 0; ByteArrayOutputStream bos = new ByteArrayOutputStream(); while((len = is.read(b)) != -1){ //把讀到的字節先寫入字節數組輸出流中存起來 bos.write(b, 0, len); } //把字節數組輸出流中的內容轉換成字符串 //Android系統默認使用utf-8編碼 text = new String(bos.toByteArray());
亂碼的出現是由於服務器端和客戶端碼錶不一致所致
text = new String(bos.toByteArray(), "gb2312");// 手動指定碼錶
GET方式提交的數據是直接拼接在url的末尾
final String path = "http://192.168.1.104/Web/servlet/CheckLogin?name=" + name + "&pass=" + pass;
發送GET請求,代碼和以前同樣
URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setReadTimeout(5000); conn.setConnectTimeout(5000); if(conn.getResponseCode() == 200){ }
瀏覽器在發送請求攜帶數據時會對數據進行URL編碼,咱們寫代碼時也須要爲中文進行URL編碼(這裏用戶名name使用了中文)
final String path = "http://192.168.1.104/Web/servlet/CheckLogin?name=" + URLEncoder.encode(name) + "&pass=" + pass;
POST提交數據是用流寫給服務器的。協議頭中多了兩個屬性:
Content-Type: application/x-www-form-urlencoded,描述提交的數據的mimetype
Content-Length: 32,描述提交的數據的長度
// 給請求頭添加post多出來的兩個屬性 String data = "name=" + URLEncoder.encode(name) + "&pass=" + pass; conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setRequestProperty("Content-Length", data.length() + "");
設置容許打開POST請求的流
conn.setDoOutput(true);
獲取鏈接對象的輸出流,往流裏寫要提交給服務器的數據
OutputStream os = conn.getOutputStream();
os.write(data.getBytes());