Android多线程下载
来源:互联网 发布:js改变div的style 编辑:程序博客网 时间:2024/04/28 20:11
开发思路:
1、首先确定开辟的线程数 int threadsize = 3;
文件的大小 int filesize ;
2、计算每条线程的下载量 int block = filesize%threadsize == 0?filesize/threadsize:filesize/threadsize+1;
3、计算出每条线程的下载开始和结束位置
for(int threadid = 0;threadid<threadsize;threadid++){//开启三条线程
int startposition = threadid*block;
int endposition = (threadid+1)*block-1;
}
4、申请网络资源
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//告诉http协议从哪里下载开始和哪里结束
conn.setRequestProperty("Range", "bytes="+startposition+"-"+endposition);
5、随机访问文件 用到RandomAccessFile 这个类
//跳转到要写入的位置
acf.seek(startposition);
类的设计
UI(MainActivity)
DownloadManager //下载管理器
int threadsize ;
public void download(String path,File dir){
//1 联网获取文件的大小
//2 计算每条线程的下载量
//3 开启线程下载
}
DownloadThread extends Thread{
String path;
int threadid;
int block;
File dir;
Listener l;
//设计一个接口(解耦合)
interface ProgressBarListener{
void getMax(int length);//最大值
void getLength(int length);//每次下载的数据量
}
在MAinActivity中
public class MainActivity extends Activity { protected static final int DOWNLOAD_ERROR = 0;protected static final int DOWNLOAD_MAX = 1;protected static final int DOWNLOAD_LENGTH = 2;private EditText et_path;private ProgressBar pb;private TextView tv_info;private DownloadManager manager;private Handler mHandler = new Handler(){public void handleMessage(android.os.Message msg) {switch (msg.what) {case DOWNLOAD_ERROR:Toast.makeText(getApplicationContext(), "下载失败", 1).show();break;case DOWNLOAD_MAX:int max = (Integer) msg.obj;pb.setMax(max);break;case DOWNLOAD_LENGTH:int length = (Integer) msg.obj;int now = pb.getProgress()+length;pb.setProgress(now);//计算百分比float precent = (float)now/pb.getMax();int info = (int) (precent*100);tv_info.setText("下载:"+info+"%");break;default:break;}};};/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); et_path = (EditText) findViewById(R.id.et_path); pb = (ProgressBar) findViewById(R.id.pb); tv_info = (TextView) findViewById(R.id.tv_info); } public void download(View v){ final String path = et_path.getText().toString(); manager = new DownloadManager(new ProgressBarListener() {public void getMax(int length) {// TODO Auto-generated method stubMessage msg = new Message();msg.what = DOWNLOAD_MAX;msg.obj = length;mHandler.sendMessage(msg);}public void getLength(int length) {// TODO Auto-generated method stubMessage msg = new Message();msg.what = DOWNLOAD_LENGTH;msg.obj = length;mHandler.sendMessage(msg);}});//判断SD卡是否存在 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ //下载耗时的操作 new Thread(){ public void run() { try {manager.download(path, Environment.getExternalStorageDirectory());} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();Message msg = new Message();msg.what = DOWNLOAD_ERROR;mHandler.sendMessage(msg);} }; }.start(); }else{ //sdcard不存在 Toast.makeText(this, "sdcard不存在", 1).show(); } }}
在DownloadManager中
public class DownloadManager {private final static int threadsize = 3;private ProgressBarListener listener;public DownloadManager(ProgressBarListener listener) {super();this.listener = listener;}/** * 下载方法 * @param path 下载路径 * @param dir 保存路径 * @throws Exception */public void download(String path,File dir) throws Exception{URL url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("POST");conn.setConnectTimeout(5000);if(conn.getResponseCode() == 200){//文件大小int filesize = conn.getContentLength();//在本地创建一个和服务上大小一样的文件File file = new File(dir, getName(path));RandomAccessFile acf = new RandomAccessFile(file, "rwd");//设置随机访问文件的长度acf.setLength(filesize);//告诉监听器listener.getMax(filesize);//计算每条线程下载量int block = filesize%threadsize==0?filesize/threadsize:filesize/threadsize+1;//开启三条线程去下载for(int threadid=0;threadid<threadsize;threadid++){new DownloadThread(threadid, path, dir, block, listener).start();}}}//获取文件的名字public String getName(String path){return path.substring(path.lastIndexOf("/")+1);}}
在DownloadThread类中
public class DownloadThread extends Thread { private int threadid; private String path; private File dir; private int block; private ProgressBarListener listener; private int startposition; private int endposition; public DownloadThread(int threadid, String path, File dir, int block, ProgressBarListener listener) { super(); this.threadid = threadid; this.path = path; this.dir = dir; this.block = block; this.listener = listener; startposition = threadid*block; endposition = (threadid+1)*block-1; } @Override public void run() { // TODO Auto-generated method stub super.run(); try { File file = new File(dir,getName(path)); RandomAccessFile acf = new RandomAccessFile(file, "rwd"); //跳转到要写入的位置 acf.seek(startposition); URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setConnectTimeout(5000); //告诉http协议从哪里下载开始和哪里结束 conn.setRequestProperty("Range", "bytes="+startposition+"-"+endposition); //不要在对相应码进行判断 InputStream is = conn.getInputStream(); byte[] buffer = new byte[1024]; int len = 0; while((len = is.read(buffer))!= -1){ //写入数据 acf.write(buffer, 0, len); listener.getLength(len); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } //获取文件的名字 public String getName(String path){ return path.substring(path.lastIndexOf("/")+1); }}
在ProgressBarListener接口中
public interface ProgressBarListener {//获取最大值public void getMax(int length);//获取每次的下载量public void getLength(int length);}
- Android -- 多线程下载, 断点下载
- Android断点下载,多线程下载
- android 多线程下载
- Android 多线程文件下载
- android多线程断点下载
- Android 多线程下载
- Android 多线程下载
- android多线程下载详解
- android多线程下载详解
- android多线程下载详解
- android多线程下载详解
- android多线程下载图片
- android多线程下载
- Android学习 多线程 下载
- android 多线程断点续传下载
- android多线程下载器
- android 多线程断点下载
- android实现多线程下载
- 即时音效
- java 多线程
- 1.14
- iOS零碎知识
- 第6周-初试“窗口”程序设计-VC++-MFCAPP工程
- Android多线程下载
- 我的权限系统设计实现MVC4 + WebAPI + EasyUI + Knockout(二)菜单导航
- Aerospike C客户端手册———Ubuntu 12 安装
- MyBatis的动态SQL详解
- Android Wifi密码查看器实现思路
- EditPlus如何实现自动换行
- 使用代理类增强业务类的功能示例
- Core Animation之多种动画效果
- ##单纯形法##