本章讲解如何去下载网络上的一些数据

开发网络应用的时候 别忘了在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 p_w_picpathView = new ImageView(MainActivity.this); 
  7.             p_w_picpathView.setImageBitmap((Bitmap) msg.obj); 
  8.             new AlertDialog.Builder(MainActivity.this).setView(p_w_picpathView) 
  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 p_w_picpathView = new ImageView(MainActivity.this); 
  7.         p_w_picpathView.setImageBitmap((Bitmap) msg.obj); 
  8.         new AlertDialog.Builder(MainActivity.this).setView(p_w_picpathView) 
  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、多线程下载网络上的文件,并打印进度