本章讲解如何去下载网络上的一些数据
开发网络应用的时候 别忘了在AndroidManifest.xml添加网络权限
- <uses-permission android:name="android.permission.INTERNET" >
网络操作是一个耗时操作,需要写在线程中~
一、通过URL来获取网络数据
看下代码 很简单 通过url对象 获取输入流
- //实例化url
- URL url = new URL(
- "http://imgsrc.baidu.com/forum/w%3D580%3B/sign=3161279c86d6277fe912323018031e30/21a4462309f790522e42f4190df3d7ca7bcbd5bc.jpg");
- //通过url获取输入流
- InputStream is = url.openStream();
举个例子 获取一张网路图片 然后在对话框中显示
- Handler handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- // TODO Auto-generated method stub
- super.handleMessage(msg);
- ImageView imageView = new ImageView(MainActivity.this);
- imageView.setImageBitmap((Bitmap) msg.obj);
- new AlertDialog.Builder(MainActivity.this).setView(imageView)
- .setPositiveButton("OK", null).show();
- }
- };
- private void getImgWithURL() {
- // TODO Auto-generated method stub
- new Thread() {
- public void run() {
- try {
- //实例化url
- URL url = new URL(
- "http://imgsrc.baidu.com/forum/w%3D580%3B/sign=3161279c86d6277fe912323018031e30/21a4462309f790522e42f4190df3d7ca7bcbd5bc.jpg");
- //通过url获取输入流
- InputStream is = url.openStream();
- Message msg = new Message();
- msg.obj = BitmapFactory.decodeStream(is);
- handler.sendMessage(msg);
- //关闭流操作
- is.close();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- };
- }.start();
- }
为什么要用到handler呢? 因为不能在子线程中更新UI
二、通过HttpURLConnection获取网络数据
HttpURLConnection是继承于URLConnection类,二者都是抽象类。其对象主要通过URL的openConnection方法获得。创建方法如下代码所示:
- // 实例化url
- URL url = new URL(
- "http://imgsrc.baidu.com/forum/w%3D580%3B/sign=3161279c86d6277fe912323018031e30/21a4462309f790522e42f4190df3d7ca7bcbd5bc.jpg");
- // 打开URL连接
- HttpURLConnection connection = (HttpURLConnection) url
- .openConnection();
HttpURLConnection默认使用GET方式,下面来写个demo 获取一张网络图片 并显示
- Handler handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- // TODO Auto-generated method stub
- super.handleMessage(msg);
- ImageView imageView = new ImageView(MainActivity.this);
- imageView.setImageBitmap((Bitmap) msg.obj);
- new AlertDialog.Builder(MainActivity.this).setView(imageView)
- .setPositiveButton("OK", null).show();
- }
- };
- private void getImgWithURL() {
- // TODO Auto-generated method stub
- new Thread() {
- public void run() {
- try {
- // 实例化url
- URL url = new URL(
- "http://imgsrc.baidu.com/forum/w%3D580%3B/sign=3161279c86d6277fe912323018031e30/21a4462309f790522e42f4190df3d7ca7bcbd5bc.jpg");
- // 打开URL连接
- HttpURLConnection connection = (HttpURLConnection) url
- .openConnection();
- // 设置超时
- connection.setConnectTimeout(5 * 1000);
- // 返回的响应码200,表示成功.
- if (connection.getResponseCode() != 200)
- throw new Exception();
- // 得到网络返回的输入流
- InputStream is = connection.getInputStream();
- Message msg = new Message();
- msg.obj = BitmapFactory.decodeStream(is);
- handler.sendMessage(msg);
- //关闭流
- is.close();
- //断开连接
- connection.disconnect();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- };
- }.start();
- }
下面讲下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(); 7)is.close();关闭流 |
连接的时候 需要注意的地方:
总结: --记得设置连接超时,如果网络不好,Android系统在超过默认时间会收回资源中断操作. --返回的响应码200,是成功. --在Android中对文件流的操作和JAVA SE上面是一样的. --在对大文件的操作时,要将文件写到SDCard上面,不要直接写到手机内存上. --操作大文件是,要一遍从网络上读,一遍要往SDCard上面写,减少手机内存的使用.这点很重要,面试经常会被问到. --对文件流操作完,要记得及时关闭. |
接下来 我们来讲实例
1、获取网络上的图片
这个就不讲了 上面的例子已经写了
2、获取网页的代码
代码基本和获取图片一样 只不过是将获取的输入流转换成String对象
- InputStream is = connection.getInputStream();
- BufferedReader reader = new BufferedReader(
- new InputStreamReader(is,"gb2312"));
- StringBuffer buffer = new StringBuffer();
- String line ;
- while ((line=reader.readLine()) != null) {
- buffer.append(line);
- }
3、获取网页上的xml
获取输入流 通过XmlPullParser 解析
4、获取网页上的json
获取输入流 转换为String对象 然后通过JSONTokener来解析
5、单线程下载网络上的文件,并打印进度
主要和上面的区别就是 需要将得到的输入流 存储到文件输出流中
- public void download() {
- // TODO Auto-generated method stub
- new Thread() {
- public void run() {
- String path = "http://zhangmenshiting.baidu.com/data2/music/2305606/10420691361764861192.mp3?xcode=5e9a399d488f1b03081926d26e957a29";
- try {
- URL url = new URL(path);
- HttpURLConnection connection = (HttpURLConnection) url
- .openConnection();
- connection.setConnectTimeout(5 * 1000);
- if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
- throw new Exception();
- // 获取输入流
- InputStream is = connection.getInputStream();
- // 创建文件输出流
- FileOutputStream fos = new FileOutputStream(
- Environment.getExternalStorageDirectory()
- + "/1.mp3");
- byte buffer[] = new byte[1024 * 4];
- // 获取文件总长
- float filesize = connection.getContentLength();
- // 记录已下载长度
- float temp = 0;
- int len = 0;
- while ((len = is.read(buffer)) != -1) {
- // 将字节写入文件输出流
- fos.write(buffer, 0, len);
- temp += len;
- System.out.println(temp / filesize * 100 + "%");
- }
- System.err.println("下载完成");
- fos.flush();
- fos.close();
- is.close();
- connection.disconnect();
- } catch (Exception e) {
- // TODO: handle exception
- e.printStackTrace();
- }
- };
- }.start();
- }
实际上很简单 结束的时候别忘了close流和discontent连接
6、多线程下载网络上的文件,并打印进度