標籤:
網狀圖片查看器
1. 確定圖片的網址
2. 發送http請求
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. 伺服器的圖片是以流的形式返回給瀏覽器的
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,需要使用訊息傳遞機制
訊息傳遞機制
主線程建立時,系統會同時建立訊息佇列(MessageQueue)對象和訊息輪詢者(Looper)對象
輪詢者的作用就是不停的檢測訊息佇列中是否有訊息(Message)
訊息佇列一旦有訊息,輪詢者就會把訊息對象傳給訊息處理器(Handler)
訊息處理器會調用handleMessage()方法來處理這條訊息,handleMessage()方法運行在主線程中,所以可以重新整理UI
android.os.Handler handler = new android.os.Handler(){ // 主線程中有一個訊息輪詢者Looper,不斷檢測訊息佇列中是否有新訊息,如果發現有新訊息,自動調用此方法,注意此方法是在主線程中啟動並執行,所以可以重新整理UI public void handleMessage(Message msg) { }};
在子線程中往訊息佇列裡發訊息
Message msg = handler.obtainMessage();// 建立訊息對象,使用handler.obtainMessage()建立訊息比直接new更節省空間的msg.obj = bm; // 訊息的obj屬性可以賦值任何對象,這個屬性使訊息可以攜帶資料msg.what = 1; // what屬性相當於一個標籤,用於區分出不同的訊息,從而運行不能的代碼handler.sendMessage(msg);// 發送訊息
通過switch語句區分不同的訊息
public void handleMessage(android.os.Message msg) { switch (msg.what) { //如果是1,說明屬於請求成功的訊息 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; } }
總結:只要訊息佇列中有訊息,handleMessage()方法就會調用。子線程如果需要重新整理UI,只需要使用處理器對象的sendMessage()方法嚮往訊息佇列中發一條訊息,觸發handleMessage()方法重新整理UI即可
加入緩衝圖片的功能
讀取伺服器返回的流裡的資料,把資料寫到本地檔案快取起來
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());
每次發送請求前檢測一下在緩衝中是否存在同名圖片,如果存在,則讀取緩衝
擷取開原始碼的網站
code.google.com
github.com
在github搜尋smart-image-view,下載開源項目smart-image-view
使用自訂群組件時,標籤名字要寫包名
<com.loopj.android.image.SmartImageView/>
SmartImageView的使用
SmartImageView siv = (SmartImageView) findViewById(R.id.siv);siv.setImageUrl("http://192.168.1.102:8080/dd.jpg");
Html源檔案查看器
發送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方式提交資料
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方式提交資料
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());
Android應用開發-網路編程(一)(重製版)