Android應用開發-網路編程(一)(重製版)

來源:互聯網
上載者:User

標籤:

 

網狀圖片查看器

 

  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應用開發-網路編程(一)(重製版)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.