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

  • 相关阅读:
    ABAP接口用法
    监听textarea数值变化
    The first step in solving any problem is recognizing there is one.
    Wrinkles should merely indicate where smiles have been.
    God made relatives.Thank God we can choose our friends.
    Home is where your heart is
    ABAP跳转屏幕
    Python 工具包 werkzeug 初探
    atom通过remote ftp同步本地文件到远程主机的方法
    Mongodb学习笔记一
  • 原文地址:https://www.cnblogs.com/begin1949/p/5060979.html
Copyright © 2011-2022 走看看