全部博文(153)
分类: LINUX
2010-12-17 09:53:21
多线程下载:
如何才能从文件的指定位置处开始下载文件?(比如从50MB开始)这一点我们可以通过HTTP请 求信息头来设置,还记得HTTP请求信息头的“Range”属性吗?
断点:
首要问题(多线程下载)已经被我们解决了,支持断点下载想必大家也已经想到了。就是将下载的进度保存到文件中,但在Android中却不能这么做。通过老黎的试验,在Android平台中,我们需要向文件中写出下载的文件数据,还需要向另一 个文件中写出下载进度,这样会出错。这样会导致有一个文件的内容没有被写出。所以我们就不能以文件的方式来保存下载进度,但可以通过数据库的方式保存下载 进度。
这两大问题我们已经有了解决思路,那么就开始动手编写吧!
1.创建Android工程
Project name:MulThreadDownloader
BuildTarget:Android2.1
Application name:多线程断点下载
Package name:com.changcheng.download
Create Activity:MulThreadDownloader
Min SDK Version:7
2.AndroidManifest.xml
xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="" package="com.changcheng.download" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".MulThreadDownloader" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> intent-filter> activity> application> <uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/> manifest> |
3.strings.xml
xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, DownloadActivity!string> <string name="app_name">多线程断点下载string> <string name="path">下载路径string> <string name="downloadbutton">下载string> <string name="sdcarderror">SDCard不存在或者写保护string> resources> |
4.main.xml
xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" >
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/path" /> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="" android:id="@+id/path" />
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/downloadbutton" android:id="@+id/button" />
<ProgressBar android:layout_width="fill_parent" android:layout_height="20dip" style="?android:attr/progressBarStyleHorizontal" android:id="@+id/downloadbar"/>
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:id="@+id/resultView" /> LinearLayout> |
5.MulThreadDownloader
package com.changcheng.download;
import java.io.File; import com.changcheng.net.download.DownloadProgressListener; import com.changcheng.net.download.FileDownloader; import com.changcheng.download.R; import android.app.Activity; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast;
public class MulThreadDownloader extends Activity { private EditText pathText; private ProgressBar progressBar; private TextView resultView; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { if(!Thread.currentThread().isInterrupted()){ switch (msg.what) { case 1: // 获取 当前文件下载的进度 int size = msg.getData().getInt("size"); progressBar.setProgress(size); int result = (int)(((float)size/(float)progressBar.getMax()) * 100); resultView.setText(result+ "%"); if(progressBar.getMax() == size){ Toast.makeText(MulThreadDownloader.this, "文件 下载完成", 1).show(); } break;
case -1: String error = msg.getData().getString("error"); Toast.makeText(MulThreadDownloader.this, error, 1).show(); break; } } super.handleMessage(msg); } };
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); pathText = (EditText)this.findViewById(R.id.path); progressBar = (ProgressBar)this.findViewById(R.id.downloadbar); resultView = (TextView)this.findViewById(R.id.resultView); Button button = (Button)this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String path = pathText.getText().toString(); if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ //下载文件需要很长的时间,主线程是不能够长时 间被阻塞,如果主线程被长时间阻塞, 那么Android被 回收应用 download(path, Environment.getExternalStorageDirectory()); }else{ Toast.makeText(MulThreadDownloader.this, R.string.sdcarderror, 1).show(); } } }); } /** * 下载 文件 * @param path 下载路径 * @param saveDir 文件保存目录 */ //对于Android的UI控 件,只能由主线程负责显示界面的更新,其他线程不能直接更新UI控 件的显示 public void download(final String path, final File saveDir){ new Thread(new Runnable() { @Override public void run() { FileDownloader downer = new FileDownloader(MulThreadDownloader.this, path, saveDir, 3); progressBar.setMax(downer.getFileSize());//设置进度条的最大刻度 try { downer.download(new DownloadProgressListener(){ @Override public void onDownloadSize(int size) { Message msg = new Message(); msg.what = 1; msg.getData().putInt("size", size); handler.sendMessage(msg);//发送消息 }}); } catch (Exception e) { Message msg = new Message(); msg.what = -1; msg.getData().putString("error", "下载 失败"); handler.sendMessage(msg); } } }).start(); } } |
chinaunix网友2010-12-17 15:01:16
很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com