zoukankan      html  css  js  c++  java
  • android网络编程之HttpUrlConnection的讲解--实现文件断点下载

    1、没有实现服务器端,下载地址为网上的一个下载链接。

    2、网络开发不要忘记在配置文件中添加访问网络的权限

    <uses-permission android:name="android.permission.INTERNET"/>

    3、网络请求、处理不能在主线程中进行,一定要在子线程中进行。因为网络请求一般有1~3秒左右的延时,在主线程中进行造成主线程的停顿,对用户体验来说是致命的。(主线程应该只进行UI绘制,像网络请求、资源下载、各种耗时操作都应该放到子线程中)。

    4、断点下载返回码为206,而不是200,不同的网站可能有区别,大家注意一下,断点请求失败的返回码为416。

    5、

    /**
     * 断点下载
     */
    public class MoreTimesActivity extends Activity {
        private TextView mTvMsg;
        
        private String result = "";
        
        private long start = 0;
        private long stop = 1024 * 1024;
        
        private int times = 0;  // 根据文件大小自己设的,
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            setContentView(R.layout.activity_times_download);
            
            initView();
        }
        
        private void initView(){
            mTvMsg = (TextView) findViewById(R.id.tv_msg);
            
            new Thread(moreThread).start();
        }
        
        private Thread moreThread = new Thread(){
            public void run() {
                HttpURLConnection connection = null;
                try {
                    URL url = new URL("http://ftp-apk.pconline.com.cn/ef19af4e28462271af1117efaf868bc2/pub/download/201010/renshengrili_v4.0.04.05.apk");
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setDoInput(true);
                    // 设置开始下载的位置和结束下载的位置,单位为字节
                    connection.setRequestProperty("Range", "bytes=" + start + "-" + stop);
                    
                    String path = Environment.getExternalStorageDirectory().getPath()  + "/aaaaa/baidu_map.apk";
                    // 断点下载使用的文件对象RandomAccessFile
                    RandomAccessFile access = new RandomAccessFile(path, "rw");
                    // 移动指针到开始位置
                    access.seek(start);
                    InputStream is = null;
                    Log.e("ADB----", connection.getResponseCode() + "");
                    if(connection.getResponseCode() == 206){
                        is = connection.getInputStream();
                        int count = 0;
                        byte[] buffer = new byte[1024];
                        while((count = is.read(buffer)) != -1){
                            access.write(buffer, 0, count);
                        }
                    }
                    
                    if(access != null){
                        access.close();
                    }
                    if(is != null){
                        is.close();
                    }
                    
                    start = stop + 1;
                    stop += 1024*1024;   // 每次下载1M
                    
                    Message msg = Message.obtain();
                    msg.what = 0;
                    result += "文件" + times + "下载成功" + ":" + start + "---" + stop + "
    ";
                    moreHandler.sendMessage(msg);
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if(connection != null){
                        connection.disconnect();
                    }
                }
            };
        };
        
        private Handler moreHandler = new Handler(){
            public void handleMessage(android.os.Message msg) {
                if(msg.what == 0 && result!=null){
                    if(times >= 10){
                        Message msg1 = Message.obtain();
                        msg1.what = 1;
                        moreHandler.sendMessage(msg1);
                    }else{
                        new Thread(moreThread).start();
                        times += 1;
                    }
                    
                    mTvMsg.setText(result);
                }else if(msg.what == 1){
                    mTvMsg.setText(result);
                }
            };
        };
    }

    6、断点下载重要的是实现一:设置断点请求setRequestProperty("Range", "bytes=0-1024");

                                     二:通过RandomAccessFile来将下载的字节插入到指定的位置。

    7、对于输出流的三个方法的对比:

        os.write(byte[] buffer);  可能错误,因为你每次读取的数据小于等于1024,但你每次写入的数据仍然是1024, 对图片有一定影响,对安装包绝对是致命的影响。
        os.write(int oneByte);    效率低
        os.write(byte[] buffer, int byteOffset, int byteCount);   效率高,和第二个方法相比有一个数量级的差别(主观上看,有兴趣的可以测几下)。

    8、如何实现多线程断点下载这里不再介绍,大家可以自己思考一下。

    9、参考博文: http://blog.sina.com.cn/s/blog_413580c20100wmr8.html

  • 相关阅读:
    8种元素定位方式
    接口MD5加密如何测试?
    web自动化测试框架 —数据驱动测试
    等待方式
    全面开展测试需求分析
    字符串格式化(%方式 与 format方式)
    Python中八大基本数据类型之 集合
    Python中 __new__ 和 __init__ 的区别
    C/S模式与B/S模式的工作原理
    剑指offer--把二叉树打印成多行
  • 原文地址:https://www.cnblogs.com/begin1949/p/5060979.html
Copyright © 2011-2022 走看看