博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HttpURLConnection实现多线程网络下载
阅读量:2490 次
发布时间:2019-05-11

本文共 5064 字,大约阅读时间需要 16 分钟。

第一步:设计布局文件如下:

运行效果如下:(以下载图片为例) 第二步:编写下载工具类(多线程下载)
public class DownUtil{    //  定义下载路径    private String path;    //  要下载到的文件路径    private String targetFile;    private int threadNum;    private DownThread[] threads;    //  定义下载文件的总大小    private int fileSize;    public DownUtil(){    }    //  初始化下载所需数据    public DownUtil(String path,String targetFile,int threadNum){        this.path = path;        this.targetFile = targetFile;        this.threadNum = threadNum;        threads = new DownThread[threadNum];    }    //  定义下载方法    public void download(){        try {            URL url = new URL(path);            //  获得到资源的链接            HttpURLConnection conn = (HttpURLConnection) url.openConnection();            conn.setRequestProperty("Accept-Encoding","identity");            conn.setConnectTimeout(5*10000);            conn.setRequestMethod("GET");            conn.setRequestProperty("Charset","UTF-8");            conn.setRequestProperty("Accept-language","zh-CN");            conn.setRequestProperty("Connection","Keep-Alive");            //  获取要下载的文件的大小            fileSize = conn.getContentLength();            conn.disconnect();            int currentPartSize = fileSize / threadNum + 1;            //  创建一个文件读取流去读取targetFile所定义的文件,权限为读写            RandomAccessFile file = new RandomAccessFile(targetFile,"rw");            file.setLength(fileSize);            file.close();            for (int i = 0; i 
0){ currentPart.write(buf,0,hasRead); length +=hasRead; } currentPart.close(); is.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } // 定义一个为InputStream跳过bytes字节的方法 // 因为输入流的skip方法有时候会读取不完整 所以创建一个读取方法循环读取知道读完为止 public static void skipFully(InputStream is,long bytes){ long remainning = bytes; long len = 0; while(remainning > 0){ try { len = is.skip(remainning); remainning -= len; } catch (IOException e) { e.printStackTrace(); } } }} 第三步:在MainActivity中编写代码,实现下载功能并预览图片,因为下载任务是个耗时操作应放在线程中操作,对于UI的改变操作应该使用handler进行处理,使用定时器和ProgressBard对下载状态进行更新和显示:
public class MainActivity extends Activity {    EditText url,target;    Button btn_download;    ProgressBar bar;    ImageView show;    DownUtil downUtill;    //  定义进度条的状态值    private int mDownStatus;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        url = (EditText) findViewById(R.id.id_url);        target = (EditText) findViewById(R.id.id_targetFile);        btn_download = (Button) findViewById(R.id.id_download);        bar = (ProgressBar) findViewById(R.id.id_progress);        show = (ImageView) findViewById(R.id.id_show);        final Handler handler = new Handler(){            public void handleMessage(Message msg){                if(msg.what == 0x123){                    if(mDownStatus == 100){                        Toast.makeText(MainActivity.this, "download task done", Toast.LENGTH_SHORT).show();                        Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/a.chm");                        show.setImageBitmap(bitmap);                    }                    bar.setProgress(mDownStatus);                }            }        };        btn_download.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                downUtill = new DownUtil(url.getText().toString(),target.getText().toString(),6);                Log.i("KKK",url.getText().toString()+"-----"+target.getText().toString());                new Thread(){                    public void run(){                        downUtill.download();                        final Timer timer = new Timer();                        timer.schedule(new TimerTask() {                            @Override                            public void run() {                                double completeRate = downUtill.getConpleteRate();                                mDownStatus = (int) completeRate * 100;                                Log.i("KKK",mDownStatus+"%");                                handler.sendEmptyMessage(0x123);                                if(mDownStatus>=100){                                    Log.i("KKK","下载完成");                                    timer.cancel();                                }                            }                        },0,100);                    }                }.start();            }        });    }} 注意事项:需要在AndroidManifest.xml中定义如下权限:
联网权限
创建删除文件权限
写入SD卡权限 所出现的问题: 1. is.getContentLength结果为0,可能是要下载的资源没有给出下载权限 或是服务器没有给出Content-Length字段,需要换一个资源下载进行测试。 2. getContentLength返回结果-1,可能是缺少 conn.setRequestProperty("Accept-Encoding","identity");这行代码。
 

转载地址:http://fhxrb.baihongyu.com/

你可能感兴趣的文章
ES相关度评分
查看>>
我们一起做一个可以商用的springboot脚手架
查看>>
idea在搭建ssm框架时mybatis整合问题 无法找到mapper
查看>>
java设计基本原则----单一职责原则
查看>>
HashMap的实现
查看>>
互斥锁 synchronized分析
查看>>
java等待-通知机制 synchronized和waity()的使用实践
查看>>
win10 Docke安装mysql8.0
查看>>
docker 启动已经停止的容器
查看>>
order by 排序原理及性能优化
查看>>
Lock重入锁
查看>>
docker安装 rabbitMq
查看>>
git 常用命令 入门
查看>>
关闭selinx nginx无法使用代理
查看>>
shell 脚本部署项目
查看>>
spring cloud zuul网关上传大文件
查看>>
springboot+mybatis日志显示SQL
查看>>
工作流中文乱码问题解决
查看>>
maven打包本地依赖包
查看>>
spring boot jpa 实现拦截器
查看>>