【Android網絡開發の5】Android中的網絡數據下載

本章講解如何去下載網絡上的一些數據

開發網絡應用的時候 別忘了在AndroidManifest.xml添加網絡權限

  1. <uses-permission android:name="android.permission.INTERNET" > 

網絡操作是一個耗時操作,需要寫在線程中~

一、通過URL來獲取網絡數據

看下代碼 很簡單  通過url對象 獲取輸入流 

  1. //實例化url   
  2. URL url = new URL( 
  3.         "http://imgsrc.baidu.com/forum/w%3D580%3B/sign=3161279c86d6277fe912323018031e30/21a4462309f790522e42f4190df3d7ca7bcbd5bc.jpg"); 
  4. //通過url獲取輸入流 
  5. InputStream is = url.openStream(); 

舉個例子  獲取一張網路圖片 然後在對話框中顯示

  1. Handler handler = new Handler() { 
  2.         @Override 
  3.         public void handleMessage(Message msg) { 
  4.             // TODO Auto-generated method stub 
  5.             super.handleMessage(msg); 
  6.             ImageView imageView = new ImageView(MainActivity.this); 
  7.             imageView.setImageBitmap((Bitmap) msg.obj); 
  8.             new AlertDialog.Builder(MainActivity.this).setView(imageView) 
  9.                     .setPositiveButton("OK"null).show(); 
  10.         } 
  11.     }; 
  12.  
  13.     private void getImgWithURL() { 
  14.         // TODO Auto-generated method stub 
  15.         new Thread() { 
  16.             public void run() { 
  17.                 try { 
  18.                     //實例化url   
  19.                     URL url = new URL( 
  20.                             "http://imgsrc.baidu.com/forum/w%3D580%3B/sign=3161279c86d6277fe912323018031e30/21a4462309f790522e42f4190df3d7ca7bcbd5bc.jpg"); 
  21.                     //通過url獲取輸入流 
  22.                     InputStream is = url.openStream(); 
  23.                     Message msg = new Message(); 
  24.                     msg.obj = BitmapFactory.decodeStream(is); 
  25.                     handler.sendMessage(msg);
  26. //關閉流操作
  27. is.close();
  28.                 } catch (Exception e) { 
  29.                     // TODO Auto-generated catch block 
  30.                     e.printStackTrace(); 
  31.                 } 
  32.             }; 
  33.         }.start(); 
  34.  
  35.     } 

爲什麼要用到handler呢? 因爲不能在子線程中更新UI

二、通過HttpURLConnection獲取網絡數據

HttpURLConnection是繼承於URLConnection類,二者都是抽象類。其對象主要通過URL的openConnection方法獲得。創建方法如下代碼所示:

  1. // 實例化url 
  2. URL url = new URL( 
  3.         "http://imgsrc.baidu.com/forum/w%3D580%3B/sign=3161279c86d6277fe912323018031e30/21a4462309f790522e42f4190df3d7ca7bcbd5bc.jpg"); 
  4. // 打開URL連接 
  5. HttpURLConnection connection = (HttpURLConnection) url 
  6.         .openConnection(); 

HttpURLConnection默認使用GET方式,下面來寫個demo 獲取一張網絡圖片 並顯示

  1. Handler handler = new Handler() { 
  2.     @Override 
  3.     public void handleMessage(Message msg) { 
  4.         // TODO Auto-generated method stub 
  5.         super.handleMessage(msg); 
  6.         ImageView imageView = new ImageView(MainActivity.this); 
  7.         imageView.setImageBitmap((Bitmap) msg.obj); 
  8.         new AlertDialog.Builder(MainActivity.this).setView(imageView) 
  9.                 .setPositiveButton("OK"null).show(); 
  10.     } 
  11. }; 
  12.  
  13. private void getImgWithURL() { 
  14.     // TODO Auto-generated method stub 
  15.     new Thread() { 
  16.         public void run() { 
  17.             try { 
  18.                 // 實例化url 
  19.                 URL url = new URL( 
  20.                         "http://imgsrc.baidu.com/forum/w%3D580%3B/sign=3161279c86d6277fe912323018031e30/21a4462309f790522e42f4190df3d7ca7bcbd5bc.jpg"); 
  21.                 // 打開URL連接 
  22.                 HttpURLConnection connection = (HttpURLConnection) url 
  23.                         .openConnection(); 
  24.                 // 設置超時 
  25.                 connection.setConnectTimeout(5 * 1000); 
  26.                 // 返回的響應碼200,表示成功. 
  27.                 if (connection.getResponseCode() != 200
  28.                     throw new Exception(); 
  29.                 // 得到網絡返回的輸入流 
  30.                 InputStream is = connection.getInputStream(); 
  31.                 Message msg = new Message(); 
  32.                 msg.obj = BitmapFactory.decodeStream(is); 
  33.                 handler.sendMessage(msg); 
  34.                 //關閉流 
  35.                 is.close(); 
  36.                 //斷開連接 
  37.                 connection.disconnect(); 
  38.  
  39.             } catch (Exception e) { 
  40.                 // TODO Auto-generated catch block 
  41.                 e.printStackTrace(); 
  42.             } 
  43.         }; 
  44.     }.start(); 
  45.  

下面講下HttpURLconnecttion連接url的步驟

1)創建一個URL對象

URL url = new URL(http://www.baidu.com);

2)利用HttpURLConnection對象從網絡中獲取網頁數據

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

3)設置連接超時

conn.setConnectTimeout(5*1000);

4)對響應碼進行判斷

if (conn.getResponseCode() != 200)    //從Internet獲取網頁,發送請求,將網頁以流的形式讀回來

throw new RuntimeException("請求url失敗");

5)得到網絡返回的輸入流

InputStream is = conn.getInputStream();
6)處理流

7)is.close();關閉流
8)conn.disconnect();通知關閉連接

連接的時候  需要注意的地方:

 總結:
--記得設置連接超時,如果網絡不好,Android系統在超過默認時間會收回資源中斷操作.
--返回的響應碼200,是成功.
--在Android中對文件流的操作和JAVA SE上面是一樣的.
--在對大文件的操作時,要將文件寫到SDCard上面,不要直接寫到手機內存上.
--操作大文件是,要一遍從網絡上讀,一遍要往SDCard上面寫,減少手機內存的使用.這點很重要,面試經常會被問到.
--對文件流操作完,要記得及時關閉.

 


接下來  我們來講實例

1、獲取網絡上的圖片

這個就不講了 上面的例子已經寫了

2、獲取網頁的代碼

代碼基本和獲取圖片一樣  只不過是將獲取的輸入流轉換成String對象

  1. InputStream is = connection.getInputStream(); 
  2. BufferedReader reader = new BufferedReader( 
  3.         new InputStreamReader(is,"gb2312")); 
  4. StringBuffer buffer = new StringBuffer(); 
  5. String line  ; 
  6. while ((line=reader.readLine()) != null) { 
  7.     buffer.append(line); 

3、獲取網頁上的xml

獲取輸入流  通過XmlPullParser 解析

4、獲取網頁上的json

獲取輸入流 轉換爲String對象  然後通過JSONTokener來解析

5、單線程下載網絡上的文件,並打印進度

主要和上面的區別就是  需要將得到的輸入流 存儲到文件輸出流中 

  1. public void download() { 
  2.         // TODO Auto-generated method stub 
  3.  
  4.         new Thread() { 
  5.             public void run() { 
  6.  
  7.                 String path = "http://zhangmenshiting.baidu.com/data2/music/2305606/10420691361764861192.mp3?xcode=5e9a399d488f1b03081926d26e957a29"
  8.                 try { 
  9.                     URL url = new URL(path); 
  10.                     HttpURLConnection connection = (HttpURLConnection) url 
  11.                             .openConnection(); 
  12.                     connection.setConnectTimeout(5 * 1000); 
  13.                     if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) 
  14.                         throw new Exception(); 
  15.  
  16.                     // 獲取輸入流 
  17.                     InputStream is = connection.getInputStream(); 
  18.                     // 創建文件輸出流 
  19.                     FileOutputStream fos = new FileOutputStream( 
  20.                             Environment.getExternalStorageDirectory() 
  21.                                     + "/1.mp3"); 
  22.                     byte buffer[] = new byte[1024 * 4]; 
  23.  
  24.                     // 獲取文件總長 
  25.                     float filesize = connection.getContentLength(); 
  26.                     // 記錄已下載長度 
  27.                     float temp = 0
  28.                     int len = 0
  29.                     while ((len = is.read(buffer)) != -1) { 
  30.                         // 將字節寫入文件輸出流 
  31.                         fos.write(buffer, 0, len); 
  32.                         temp += len; 
  33.                         System.out.println(temp / filesize * 100 + "%"); 
  34.                     } 
  35.                     System.err.println("下載完成"); 
  36.                     fos.flush(); 
  37.                     fos.close(); 
  38.                     is.close(); 
  39.                     connection.disconnect(); 
  40.                 } catch (Exception e) { 
  41.                     // TODO: handle exception 
  42.                     e.printStackTrace(); 
  43.                 } 
  44.             }; 
  45.         }.start(); 
  46.     } 

實際上很簡單   結束的時候別忘了close流和discontent連接

6、多線程下載網絡上的文件,並打印進度

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章