[Android應用開發] 03.網路編程

來源:互聯網
上載者:User

標籤:

前言
  • 網路編程不難,主要要掌握幾點就可以。
  • 使用HttpURLConnection進行網路編程。
  • 如果在主線程進行網路編程操作,android會拋出異常,要另起一個線程進行網路代碼邏輯操作。
  • 更新UI介面,要用handler和message。瞭解looper機制。
  • 熟悉get請求和post的請求,並知道二者的不同。
  • 下文用幾個例子來讓我們更多的瞭解怎麼進行網路編程。

    • 網狀圖片查看器
    • smart-image-view(項目),推薦閱讀下源碼
    • 下載圖片,放在緩衝目錄下(data/data/【項目包名】/cache),關於緩衝目錄,參看[Android應用開發02]/使用路徑api讀寫儲存讀寫檔案部分。
    • 頁面源碼查看器。
    網狀圖片查看器

    確定圖片的網址

  • 發送http請求

      URL url = new URL(address);  //擷取連線物件,並沒有建立串連  HttpURLConnection conn = (HttpURLConnection) url.openConnection();  //設定串連和讀取逾時  conn.setConnectTimeout(5000);  conn.setReadTimeout(5000);  //佈建要求方法,注意必須大寫  conn.setRequestMethod("GET");  //建立串連,發送get請求  //conn.connect();  //建立串連,然後擷取響應嗎,200說明請求成功  conn.getResponseCode();
  • 伺服器的圖片是以流的形式返回給瀏覽器的

      //拿到伺服器返回的輸入資料流  InputStream is = conn.getInputStream();  //把流裡的資料讀取出來,並構造成圖片  Bitmap bm = BitmapFactory.decodeStream(is);
  • 把圖片設定為ImageView的顯示內容

      ImageView iv = (ImageView) findViewById(R.id.iv);  iv.setImageBitmap(bm);
  • 添加許可權

主線程不能被阻塞
  • 在Android中,主線程被阻塞會導致應用不能重新整理ui介面,不能響應使用者操作,使用者體驗將非常差

  • 主線程阻塞時間過長,系統會拋出ANR異常

    • UI停止重新整理,應用無法響應使用者操作
  • 耗時操作不應該在主線程進行

  • ANR

    • application not responding

    • 應用無響應異常

    • 主線程阻塞時間過長,就會拋出ANR

  • 任何耗時操作都不可以寫在主線程

  • 因為網路互動屬於耗時操作,如果網速很慢,代碼會阻塞,所以網路互動的代碼不能運行在主線程

  • 主線程又稱UI線程,因為只有在主線程中,才能重新整理UI

只有主線程能重新整理ui
  • 重新整理ui的代碼只能運行在主線程,運行在子線程是沒有任何效果的

  • 如果需要在子線程中重新整理ui,使用訊息佇列機制

訊息佇列
  • Looper一旦發現Message Queue中有訊息,就會把訊息取出,然後把訊息扔給Handler對象,Handler會調用自己的handleMessage方法來處理這條訊息

  • handleMessage方法運行在主線程

  • 主線程建立時,訊息佇列和輪詢者對象就會被建立,但是訊息處理器對象,需要使用時,自行建立

  • 總結:只要訊息佇列有訊息,handleMessage方法就會調用

  • 子線程如果需要重新整理ui,只需要往訊息佇列中發一條訊息,觸發handleMessage方法即可

  • 子線程使用處理器對象的sendMessage方法發送訊息

      //訊息佇列  Handler handler = new Handler(){      //主線程中有一個訊息輪詢者looper,不斷檢測訊息佇列中是否有新訊息,如果發現有新訊息,自動調用此方法,注意此方法是在主線程中啟動並執行      public void handleMessage(android.os.Message msg) {      }  };
  • 在子線程中往訊息佇列裡發訊息

      //建立訊息對象  Message msg = new Message();  //訊息的obj屬性可以賦值任何對象,通過這個屬性可以攜帶資料  msg.obj = bm;  //what屬性相當於一個標籤,用於區分出不同的訊息,從而運行不能的代碼  msg.what = 1;  //發送訊息  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;      }         }
加入緩衝圖片的功能
  • 把伺服器返回的流裡的資料讀取出來,然後通過檔案輸入資料流寫至本地檔案

      //1.拿到伺服器返回的輸入資料流  InputStream is = conn.getInputStream();  //2.把流裡的資料讀取出來,並構造成圖片  FileOutputStream fos = new FileOutputStream(file);  byte[] b = new byte[1024];  int len = 0;  while((len = is.read(b)) != -1){      fos.write(b, 0, len);  }
  • 建立bitmap對象的代碼改成

      Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath());
  • 每次發送請求前檢測一下在緩衝中是否存在同名圖片,如果存在,則讀取緩衝

擷取開原始碼的網站
  • 這個智能圖片sdk非常好用!

  • github.com

  • 在github搜尋smart-image-view

  • 下載開源項目smart-image-view

  • 使用自訂群組件時,標籤名字要寫包名

      <com.sinyee.babybus.SmartImageView/>
  • SmartImageView的使用

      SmartImageView siv = (SmartImageView) findViewById(R.id.siv);  siv.setImageUrl("http://192.168.1.10:8080/dd.jpg");
Html源檔案查看器
  • 發送GET請求

      URL url = new URL(path);  //擷取連線物件  HttpURLConnection conn = (HttpURLConnection) url.openConnection();  //設定串連屬性  conn.setRequestMethod("GET");  conn.setConnectTimeout(5000);  conn.setReadTimeout(5000);  //建立串連,擷取響應嗎  if(conn.getResponseCode() == 200){  }
  • 擷取伺服器返回的流,從流中把html源碼讀取出來

      byte[] b = new byte[1024];  int len = 0;  ByteArrayOutputStream bos = new ByteArrayOutputStream();  while((len = is.read(b)) != -1){      //把讀到的位元組先寫入位元組數組輸出資料流中存起來      bos.write(b, 0, len);  }  //把位元組數組輸出資料流中的內容轉換成字串  //預設使用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編碼

      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());

 

 

本站文章為 寶寶巴士 SD.Team 原創,轉載務必在明顯處註明:(作者官方網站: 寶寶巴士 ) 
轉載自【寶寶巴士SuperDo團隊】 原文連結: http://www.cnblogs.com/superdo/p/4890916.html

 

 

[Android應用開發] 03.網路編程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.