- 浏览: 35378 次
- 性别:
-
文章分类
最新评论
-
huangyingwu:
楼主,能给我份源码吗,我的邮件是38651207@gmail. ...
基于Android平台的NFC技术的应用实现 -
wenjiefeng:
@Override public void onResume( ...
基于Android平台的NFC技术的应用实现 -
wenjiefeng:
楼主,谢谢你的分享,能给我份源码吗,谢谢了,我的号是 1297 ...
基于Android平台的NFC技术的应用实现 -
AnhuiOSS技术分享:
煜闷_唔再肤浅 写道楼主有成功测试吗?
最近在调试这个,一直提 ...
google in-app-billing 应用内付费的简介与实现 -
煜闷_唔再肤浅:
楼主有成功测试吗?最近在调试这个,一直提示"不支持付 ...
google in-app-billing 应用内付费的简介与实现
Android开发中经常会遇到文件的下载,而下载的时间与网络状态和被下载文件的大小等因素有关。本文会对单线程下载和多线程下载做简要说明。无论哪种操作,最终都是基于HTTP(HTTPS)的网络访问。
先看看基本的一个操作流程,然后对于每一个操作步骤逐一实现就可以了。
基本流程:
- 设置连接属性;
- 建立连接;
- 获得需要的资源;
- 释放资源;
说明:这个流程是相对的,每个人可以根据具体情况而定。:)
1、在普通Java项目中下载文件: 为了简化问题,我们先不考虑在Android中实现过程,仅仅实现一个下载并保存网络资源的操作。
代码如下:
import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; public class FileDownload { /** * @param args */ public static void main(String[] args) { downloadFile("http://image.tianjimedia.com/uploadImages/2012/153/2H4Y79KZF2X3.jpg", "image.jpg"); downloadFile("http://www.google.com", "message.txt"); } private static void downloadFile(String urlPath, String filePath) { InputStream inputStream = null; ByteArrayOutputStream byteArrayOutputStream = null; byte[] data = null; try { URL url = new URL(urlPath); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(6 * 1000); conn.connect(); if (conn.getResponseCode() == 200) { inputStream = conn.getInputStream(); byteArrayOutputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length = -1; while ((length = inputStream.read(buffer)) != -1) { byteArrayOutputStream.write(buffer, 0, length); } data = byteArrayOutputStream.toByteArray(); } } catch (Exception e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e1) { e1.printStackTrace(); } } if (byteArrayOutputStream != null) { try { byteArrayOutputStream.close(); } catch (IOException e1) { e1.printStackTrace(); } } } if (data != null) { File file = new File(filePath); FileOutputStream outputStream = null; try { outputStream = new FileOutputStream(file); outputStream.write(data); } catch (Exception e) { e.printStackTrace(); } finally { if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } } }
说明:
1、InputStream inputStream = null;和ByteArrayOutputStream byteArrayOutputStream = null;之所以在try-catch外定义,是为了可以在finally代码块中可以访问,并释放该资源。在回收资源时,最好把不同资源放在单独的try-catch块中做资源释放操作,否则可能造成资源泄漏。
InputStream inputStream = null; ByteArrayOutputStream byteArrayOutputStream = null; try { ...... } catch (Exception e) { e.printStackTrace(); } finally { try { if (inputStream != null) { inputStream.close(); } if (byteArrayOutputStream != null) { byteArrayOutputStream.close(); } } catch (Exception e) { e.printStackTrace(); } }
如果采用上述资源释放代码,当inputStream和byteArrayOutputStream都不为null时,如果inputStream.close();发生异常,将导致byteArrayOutputStream.close();不被执行,从而没有释放该资源。
2、conn.setRequestMethod("GET");和conn.setConnectTimeout(6 * 1000);是设置连接属性。还有其它属性,如果需要的话,可以进行设定。
3、conn.connect();建立连接。
4、conn.getInputStream();获得连接后的输入流,从中可以获得数据。
5、在finally代码块中对申请的资源进行释放。
运行该项目,会在项目的根目录下看到两个文件,image.jpg和message.txt,如图所示:
2、在Android项目中下载文件:
a、对UI的设计:
主Activity中有两个Button,分别启动另外的两个Activity,来实现图片的下载显示和网页内容的获得并显示。布局文件就补贴出来了,会在附件中提供源码。
b、主Activity没有什么好说的,下面对另外两个Activity做详细说明:
DownloadImageActivity:
package com.anhuioss.download; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import android.app.Activity; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.text.TextUtils; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; public class DownloadImageActivity extends Activity implements OnClickListener { private EditText filePathEditText; private Button downloadButton; private ImageView imageDisplay; private Handler handler = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_download_image); filePathEditText = (EditText) findViewById(R.id.adi_image_path); downloadButton = (Button) findViewById(R.id.adi_button_download); imageDisplay = (ImageView) findViewById(R.id.adi_image); downloadButton.setOnClickListener(this); } @Override public void onClick(View v) { if (v == downloadButton) { if (!Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) { return; } String path = filePathEditText.getText().toString(); if (!TextUtils.isEmpty(path)) { downloadButton.setEnabled(false); imageDisplay.setImageDrawable(null); downloadFile(path, Environment.getExternalStorageDirectory() + File.separator + "image.jpg"); } } } private void downloadFile(final String urlPath, final String filePath) { new Thread(new Runnable() { @Override public void run() { InputStream inputStream = null; ByteArrayOutputStream byteArrayOutputStream = null; byte[] data = null; try { URL url = new URL(urlPath); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(6 * 1000); conn.connect(); if (conn.getResponseCode() == 200) { inputStream = conn.getInputStream(); byteArrayOutputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length = -1; while ((length = inputStream.read(buffer)) != -1) { byteArrayOutputStream.write(buffer, 0, length); } data = byteArrayOutputStream.toByteArray(); } } catch (Exception e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e1) { e1.printStackTrace(); } } if (byteArrayOutputStream != null) { try { byteArrayOutputStream.close(); } catch (IOException e1) { e1.printStackTrace(); } } } if (data != null) { File file = new File(filePath); FileOutputStream outputStream = null; try { outputStream = new FileOutputStream(file); outputStream.write(data); handler.post(new Runnable() { @Override public void run() { downloadButton.setEnabled(true); Drawable drawable = null; try { drawable = Drawable.createFromPath(filePath); } catch (Error e) { e.printStackTrace(); } imageDisplay.setImageDrawable(drawable); } }); } catch (Exception e) { e.printStackTrace(); } finally { if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } } }).start(); } }
说明:
1、private Handler handler = new Handler();handler的作用是在下载线程中完成下载后在UI线程里面更新UI。
2、由于示例中需要用到SDCARD,所以在做下载操作时,如果没有挂载SDCARD时,不进行下载处理:
if (!Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) { return; }
3、
handler.post(new Runnable() { @Override public void run() { downloadButton.setEnabled(true); Drawable drawable = null; try { drawable = Drawable.createFromPath(filePath); } catch (Error e) { e.printStackTrace(); } imageDisplay.setImageDrawable(drawable); } });
利用handler的post方法,在UI线程里面更新UI。首先使能按钮,其次创建drawable,最后显示图片。
3、运行项目,查看效果: 在运行前,不要忘记在Manifest文件中添加网络访问和访问SDCARD的权限哦!
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
下载图片的效果如下:
获取网页内容的页面效果:
4、多线程文件下载,直接看普通Java项目中相关操作的代码:
import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; public class FileDownloadMultiThread { public static void main(String[] args) { downloadFile(); } private static void downloadFile() { String fileName = "mysql.chm"; String urlPath = "http://192.168.1.106/mysql.chm"; // 下载开始前,创建RandomAccessFile并设置文件大小 RandomAccessFile file = null; try { // 创建URL对象 URL url = new URL(urlPath); // 创建HttpURL连接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 设置请求属性 conn.setConnectTimeout(6 * 1000); conn.setRequestMethod("GET"); // 连接 conn.connect(); // 需要下载文件的长度 int fileLength = conn.getContentLength(); // 创建RandomAccessFile并设置文件大小 file = new RandomAccessFile(fileName, "rw"); file.setLength(fileLength); // 启动的线程数量 int threadCount = 6; // 计算每个线程需要下载数据的长度 int threadDownloadLength = fileLength % 3 == 0 ? fileLength / 3 : fileLength / 3 + 1; // 创建threadCount个下载线程 for (int i = 0; i < threadCount; i++) { // 计算开始位置 int startPosition = i * threadDownloadLength; // 创建匿名下载线程对象 new MultiDownloadThread(fileName, urlPath, startPosition).start(); } } catch (Exception e) { e.printStackTrace(); } finally { // 资源释放 if (file != null) { try { file.close(); } catch (IOException e) { e.printStackTrace(); } } } } static class MultiDownloadThread extends Thread { private String urlPath; private int startPosition; private RandomAccessFile accessFile; public MultiDownloadThread(String fileName, String urlPath, int startPosition) { this.urlPath = urlPath; this.startPosition = startPosition; try { accessFile = new RandomAccessFile(fileName, "rw"); accessFile.seek(startPosition); } catch (Exception e) { e.printStackTrace(); } } public void run () { InputStream inputStream = null; try { URL url = new URL(urlPath); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(6 * 1000); conn.setRequestMethod("GET"); // 设置HTTP的Range字段,指定该线程从文件的什么位置开始下载 conn.setRequestProperty("Range", "bytes=" + startPosition + "-"); conn.connect(); inputStream = conn.getInputStream(); byte[] buffer = new byte[1024]; int readLength = -1; int totalLength = 0; while ((readLength = inputStream.read(buffer)) != -1) { accessFile.write(buffer, 0, readLength); totalLength = totalLength + readLength; } } catch (Exception e) { e.printStackTrace(); } finally { if (accessFile != null) { try { accessFile.close(); } catch (IOException e) { e.printStackTrace(); } } if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } } }
说明:
1、RandomAccessFile类创建目标文件并设置文件大小;
2、HttpURLConnection.setRequestProperty("Range", "bytes=" + startPosition + "-");方法指定下载位置;
3、RandomAccessFile.seek();设置文件指针偏移量,保存下载内容到指定位置;
4、由于线程的创建和销毁过程,线程之间的上下文切换等都需要系统资源,所以threadCount不是越大越好,而是根据具体情况进行设定;
4、在Android上实现多线程下载的方法类似,注意Android环境的特性就可以了,再次不再赘述!:)
5、多说一句: HTTP(HTTPS)的连接到网络上的数据资源的方式和设置多种多样,本例仅仅是从一个角度进行说明,希望对你有所帮助!如果需要Android项目源码,请查看附件!:)
- DownloadFile.zip (72.7 KB)
- 下载次数: 15
发表评论
-
简单混合应用开发
2013-05-13 15:31 1418移动应用开发的方式: 移动应用开发的方式,目前主要有三种 ... -
基于Android平台的NFC技术的应用实现
2012-11-29 14:25 8166近距离无线通信 ... -
Android 动画之帧动画
2012-11-20 14:26 1111帧动画是根据视觉停留原理而实现的动画效果,本例从Ani ... -
Android 动画之补间动画
2012-11-19 23:56 1334补间动画是指定开始和结束的图像状态,自动生成需要显示的 ... -
google in-app-billing 应用内付费的简介与实现
2012-10-29 11:04 6142android平台下, 谷歌应用收费提供了最新的go ... -
Android 支持不同(本地化、屏幕、版本)设备
2012-10-22 10:24 1614Android 支持不同(本地化、屏幕、版本) 设备 ...
相关推荐
一个Android文件下载Download程序示例,文件会下载至local端,远程安装程序(请输入URL),取得远程文件,取得URL,创建连接,InputStream 下载文件,创建临时文件,取得站存盘案路径,将文件写入暂存盘,在手机上打开文件的...
综上所述,实现Android文件的断点续传下载主要依赖于Java的RandomAccessFile类和多线程技术,通过精确控制文件的读写位置和下载范围,确保下载的连续性和可靠性。这种技术不仅提高了用户的下载体验,也在一定程度上...
与网上流传一个itcast的多线程下载的示例不同, ...可能需要进一步优化,本示例下载同样大小的文件需要6-7秒(下载速度都是200K左右) 暂不支持断点、多个文件同时下载, 架构清晰,可重复利用,如有问题欢迎斧正
本示例"Android文件下载Demo(可断点续传)"提供了一个实现多线程下载并且支持断点续传功能的源代码DEMO。下面将详细解释这个Demo中涉及的关键知识点。 1. **多线程下载**: 在Android中,为了提高文件下载速度,...
在Android平台上,开发一个应用程序以实现下载Word文档并顺利打开是一项常见的需求。下面将详细讲解这一过程中的关键知识点,以及如何结合给定的资源进行操作。 1. **Android权限管理**: 在Android中,访问网络和...
在Android平台上,文件下载是一项常见的任务,特别是在处理大型文件或多媒体资源时,为了提升用户体验,开发者通常会采用多线程下载并实现断点续传功能。断点续传允许用户在下载过程中暂停、恢复,避免因网络问题或...
最后,这个压缩包中的“android文件下载存储demo”项目,尽管可能需要自行调试才能运行,但它提供了一种基础结构,你可以从中学习如何组织代码、如何处理网络请求,以及如何在Android环境中实现文件的存取和解压。...
十分有用的共享资源十分有用的共享资源十分有用的共享资源。
Java 和 Android 文件下载断点续传概要 在本文中,我们将对 Java 和 Android 文件下载断点续传的概要进行详细的介绍。断点续传是一种常用的文件下载技术,它可以在下载过程中发生意外中断时,继续从中断的地方继续...
java和Android文件下载断点续传和图片下载代码实现, 可直接复制代码, 实现多种文件下载,
下载程序下载器,下载管理器、文件下载管理器、文件下载管理器、文件下载管理器、文件下载管理器、文件下载管理器、文件下载管理器、文件下载管理器、文件下载管理器、文件下载管理器、文件下载管理器、文件下载管理...
在Android平台上实现文档下载功能,特别是对于Word文档的下载,是一项常见的需求,尤其对于移动应用开发者来说。这个“android文档下载”主题主要涉及到以下几个关键知识点: 1. **Android权限管理**: 在Android...
在Android开发中,断点下载是一项重要的功能,它允许用户在中断网络连接后从上次停止的位置继续下载大文件,如应用程序、音乐或视频。本文将深入探讨如何在Android平台上实现断点下载,包括其原理、步骤以及核心代码...
Aria 是一个高性能、轻量级、易于使用的文件下载框架,主要应用于 Android 平台,目前在 GitHub 上有超过 5600 个 Star。 Aria 提供了丰富的 API,让用户可以方便地管理下载任务,包括添加、暂停、取消以及查询等...
在Android平台上,利用Http协议进行文件下载是一项常见的任务,它涉及到网络编程、多线程、文件操作等多个技术领域。本文将深入探讨如何在Android中实现这个功能,主要围绕标题“Android利用Http下载文件”和提供的...
本教程将深入探讨如何利用Service组件在Android设备上实现文件的后台下载,确保即使用户退出应用程序,文件下载也能继续进行。 ### 1. Android Service基础知识 Service是Android四大组件之一,它在后台运行,没有...
这个demo演示从网上下载文件并保存到手机,demo中可以下载一个XML文件并在Console窗口输出,还可以下载一个MP3文件并保存到手机存储目录中的BoBoMusic文件夹中,下载保存成功会返回:0。(XML和MP3文件我已经传到...
官网最新Android API开发文档,为不方便下载的亲打包上传,一共6个分卷,解压任意一个,文档无加密。文档为HTML类型。
Android API 中文文档 Android API 中文文档 Android API 中文文档 Android API 中文文档 Android API 中文文档 Android API 中文文档 Android API 中文文档 Android Android API 中文文档 中文文档Android API ...
Android 端本地预览 PDF 文件,使用 AS2.3.3 Gradle 4.1 下载下来可以直接编译运行,内部支持加载本地 File ,也可以加载一个 URL 类型的 PDF 文件,如果恰恰你的 APP 不想调用第三方软件的话 这个 DEMO 非常适合你...