zoukankan      html  css  js  c++  java
  • Android 文件下载三种基本方式

    一、自己封装URLConnection 连接请求类

       public void downloadFile1() {
        try{
            //下载路径,如果路径无效了,可换成你的下载路径
            String url = "http://c.qijingonline.com/test.mkv";
            String path = Environment.getExternalStorageDirectory().getAbsolutePath();
    
            final long startTime = System.currentTimeMillis();
            Log.i("DOWNLOAD","startTime="+startTime);
            //下载函数
           String filename=url.substring(url.lastIndexOf("/") + 1);
            //获取文件名
            URL myURL = new URL(url);
            URLConnection conn = myURL.openConnection();
            conn.connect();
            InputStream is = conn.getInputStream();
            int fileSize = conn.getContentLength();//根据响应获取文件大小
            if (fileSize <= 0) throw new RuntimeException("无法获知文件大小 ");
            if (is == null) throw new RuntimeException("stream is null");
            File file1 = new File(path);
            if(!file1.exists()){
                file1.mkdirs();
            }
            //把数据存入路径+文件名
            FileOutputStream fos = new FileOutputStream(path+"/"+filename);
            byte buf[] = new byte[1024];
            int downLoadFileSize = 0;
            do{
                //循环读取
                int numread = is.read(buf);
                if (numread == -1)
                {
                    break;
                }
                fos.write(buf, 0, numread);
                downLoadFileSize += numread;
                //更新进度条
            } while (true);
    
            Log.i("DOWNLOAD","download success");
            Log.i("DOWNLOAD","totalTime="+ (System.currentTimeMillis() - startTime));
    
            is.close();
        } catch (Exception ex) {
            Log.e("DOWNLOAD", "error: " + ex.getMessage(), ex);
        }
    }
    这种方式在Android 刚兴起的时候,很少下载封装框架,就自己封装了。虽然一般的文件都能下载,但这种方式缺点很多,不稳定或者各种各样的问题会出现。
     

    二、Android自定的下载管理(会在notification 显示下载的进度,同时可以暂停、重新连接等)

    private void downloadFile2(){
        //下载路径,如果路径无效了,可换成你的下载路径
        String url = "http://c.qijingonline.com/test.mkv";
        //创建下载任务,downloadUrl就是下载链接
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
        //指定下载路径和下载文件名
        request.setDestinationInExternalPublicDir("", url.substring(url.lastIndexOf("/") + 1));
        //获取下载管理器
        DownloadManager downloadManager= (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
        //将下载任务加入下载队列,否则不会进行下载
        downloadManager.enqueue(request);
    }

     这种方式其实就是交给了Android系统的另一个app去下载管理。这样的好处不会消耗该APP的 CPU资源。缺点是:控制起来很不灵活。

    三、使用第三方 okhttp 网络请求框架

    private void downloadFile3(){
        //下载路径,如果路径无效了,可换成你的下载路径
        final String url = "http://c.qijingonline.com/test.mkv";
        final long startTime = System.currentTimeMillis();
        Log.i("DOWNLOAD","startTime="+startTime);
    
        Request request = new Request.Builder().url(url).build();
        new OkHttpClient().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 下载失败
                e.printStackTrace();
                Log.i("DOWNLOAD","download failed");
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Sink sink = null;
                BufferedSink bufferedSink = null;
                try {
                    String mSDCardPath= Environment.getExternalStorageDirectory().getAbsolutePath();
                    File dest = new File(mSDCardPath,   url.substring(url.lastIndexOf("/") + 1));
                    sink = Okio.sink(dest);
                    bufferedSink = Okio.buffer(sink);
                    bufferedSink.writeAll(response.body().source());
    
                    bufferedSink.close();
                    Log.i("DOWNLOAD","download success");
                    Log.i("DOWNLOAD","totalTime="+ (System.currentTimeMillis() - startTime));
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.i("DOWNLOAD","download failed");
                } finally {
                    if(bufferedSink != null){
                        bufferedSink.close();
                    }
    
                }
            }
        });
    }
    okhttp是一个很有名气的开源框架,目前已经很多大公司都直接使用它作为网络请求库(七牛云SDK, 阿里云SDK)。 且里面集成了很多优势,包括 okio (一个I/O框架,优化内存与CPU)。
     
    在接收数据的时候使用了 okio框架 来做一些I/O处理,okio框架是弥补Java.io 上的不足,节省CPU与内存资源,但这个例子,我没还没看到其效果,也可以自己来接收字符流,然后获取下载的进度
     public void downloadFile(){
            final String url = "http://c.qijingonline.com/test.mkv";
            final long startTime = System.currentTimeMillis();
            Log.i("DOWNLOAD","startTime="+startTime);
            OkHttpClient okHttpClient = new OkHttpClient();
    
            Request request = new Request.Builder().url(url).build();
            okHttpClient.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    // 下载失败
                    e.printStackTrace();
                    Log.i("DOWNLOAD","download failed");
                }
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    InputStream is = null;
                    byte[] buf = new byte[2048];
                    int len = 0;
                    FileOutputStream fos = null;
                    // 储存下载文件的目录
                    String savePath = Environment.getExternalStorageDirectory().getAbsolutePath();
                    try {
                        is = response.body().byteStream();
                        long total = response.body().contentLength();
                        File file = new File(savePath, url.substring(url.lastIndexOf("/") + 1));
                        fos = new FileOutputStream(file);
                        long sum = 0;
                        while ((len = is.read(buf)) != -1) {
                            fos.write(buf, 0, len);
                            sum += len;
                            int progress = (int) (sum * 1.0f / total * 100);
                            // 下载中
    //                        listener.onDownloading(progress);
                        }
                        fos.flush();
                        // 下载完成
    //                    listener.onDownloadSuccess();
                        Log.i("DOWNLOAD","download success");
                        Log.i("DOWNLOAD","totalTime="+ (System.currentTimeMillis() - startTime));
                    } catch (Exception e) {
                        e.printStackTrace();
    //                    listener.onDownloadFailed();
                        Log.i("DOWNLOAD","download failed");
                    } finally {
                        try {
                            if (is != null)
                                is.close();
                        } catch (IOException e) {
                        }
                        try {
                            if (fos != null)
                                fos.close();
                        } catch (IOException e) {
                        }
                    }
                }
            });
        }
     
     
     
    综合来看,第三种方案是最佳的,是目前最流行的下载方案。
  • 相关阅读:
    (转)[Android实例] 关于使用ContentObserver监听不到删除短信会话的解决方案
    (转)Android 使用com.j256.ormlite
    Android中判断网络连接是否可用及监控网络状态
    2018/11/12-操作系统课笔记
    mysql的ONLY_FULL_GROUP_BY语义 --转自http://www.wtoutiao.com/p/19dh3ec.html
    nginx相关配置说明
    为重负网络优化 Nginx 和 Node.js --引用自https://linux.cn/article-1314-1.html
    windows环境下局域网内无法访问apache站点
    27个知名企业品牌VI视觉识别系统规范手册
    TopShelf&Quartz.Net实现多任务的值守
  • 原文地址:https://www.cnblogs.com/xiaoxiaoqingyi/p/7003241.html
Copyright © 2011-2022 走看看