android webview下载以及断点续传

game.gif

Android部分代码

所有下载线程的信息会存储再hashmap中,但是这个是线程不安全的。不过我们只是用来存一些数据用来返回给前端进度。

 /**
     * 当前下载对象
     * {
     * key: name 线程名
     * value : {
     * key:filelength 文件总大小
     * key:state 文件状态
     * key:haveDownloaded 当前下载量
     * }
     * }
     */
    public Map planMap = new HashMap<>();

每次请求会创建一个线程进行下载,代码每次写入会有一定的性能损失,可以先缓存部分然后再一次性写入。


/**
     * 下载文件
     *
     * @param uri 下载地址
     * @throws Exception
     */
    @JavascriptInterface
    public void downLoad(String uri) throws Exception {
        Plan verify = planMap.get(getFileName(uri));
        if (verify == null || (!verify.state && verify.haveDownloaded < verify.filelength)) {
            new Thread() {//子线程
                public void run() {
                    try {
                        //获取服务器上文件的大小
                        HttpClient client = new DefaultHttpClient();
                        HttpHead request = new HttpHead(uri);
                        HttpResponse response = client.execute(request);
                        //response  只有响应头  没有响应体
                        if (response.getStatusLine().getStatusCode() == 200) {
                            Header[] headers = response.getHeaders("Content-Length");
                            String value = headers[0].getValue();
                            //文件大小
                            Long filelength = Long.parseLong(value);
                            Log.i("下载文件", "filelength:" + filelength);
                            //在sdcard创建和服务器大小一样的文件
                            String name = getFileName(uri);
                            File file = new File("/data/data/" + mContext.getPackageName() + "/files", name + ".downLoad");
                            if ((file.exists() && file.length() < filelength) || !file.exists()) {
                                //随机访问文件
                                RandomAccessFile raf = new RandomAccessFile(file, "rwd");
                                //修改下载的开始位置   重新下载
                                Long start = file.length();
                                HttpGet httpget = new HttpGet(uri);
                                httpget.addHeader("Range", "bytes=" + start + "-");//添加请求头
                                response = client.execute(httpget);
                                InputStream inputStream = response.getEntity().getContent();
                                //跳转到起始位置
                                raf.seek(start);
                                //把流写入到文件
                                byte[] buffer = new byte[65536];
                                int len = 0;
                                Plan plan = planMap.get(getFileName(uri));
                                if (plan == null)
                                    plan = new Plan();
                                plan.filelength = filelength;
                                plan.haveDownloaded = start;
                                plan.state = true;
                                planMap.put(name, plan);//当前线程数据更新
                                /*更新下载文件列表*/
                                updateFiles();
                                while ((len = inputStream.read(buffer, 0, buffer.length)) != -1 && plan.state) {
                                    //写数据
                                    raf.write(buffer, 0, len);
                                    plan.haveDownloaded += len;//当前下载数
                                    //模拟  看到进度条动的效果
//                                    SystemClock.sleep(50);
                                }
                                httpget.releaseConnection(); 
                                inputStream.close();
                                //关闭
                                raf.close();
                                if (file.length() == filelength) {
                                    file.renameTo(new File("/data/data/" + mContext.getPackageName() + "/files", name));
                                    /*更新下载文件列表*/
                                    updateFiles();
                                }
                                Log.i("下载", name + "下载结束");
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                ;
            }.start();
        }
    }

一个用到的实体类,用来传给前端当前下载的信息


class Plan {
    /**
     * 总大小
     */
    Long filelength;
    /**
     * 代表当前线程状态 true进行中 false 暂停
     */
    Boolean state;
    /**
     * 当前已下载的数据量
     */
    long haveDownloaded;
}

updateFiles这个方法是用来读取当前目录下的文件用的,有getFiles的方法给前端调用,
作用是 重启APP后获取下载记录。
代码就不贴上来了。
所有代码只提供参考思路,拒绝缝合怪

你可能感兴趣的:(android webview下载以及断点续传)