Android上Java网络资源访问(二)使用HttpURLConnection多线程下载

2017-09-13 20:36:31来源:CSDN作者:wolfboy2人点击

分享

对网络访问不太了解的新手,可以先看一下上一篇文章对URL的简单介绍:Android上Java网络资源访问(一)使用URL类访问

1.简介 

HttpURLConnection继承于URLConnection,可以访问指定网站,HttpURLConnection通过对URLConnection的封装,使开发者在使用的过程中能够更加的方便;

URLConnection类可以使用上篇文章介绍的URL类获取,方法如下:

URLConnection connection = realUrl.openConnection();

URLConnection有多种请求方式:

摘抄如下:

Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的4个操作。到这里,大家应该有个大概的了解了,GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。

具体参考文章:浅谈HTTP中Get与Post的区别
但是虽然URLConnection有多种交互方式,但是我们主要使用GET和POST这两种方式;

GET与POST请求。二者的区别主要在于:
a:) get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet,
b:) post与get的不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。

2. 多线程下载实例

该实例使用android应用开发,编写一个多线程下载的工具类:DownUtil,在一个界面中,一个输入框输入下载文件的url地址,一个输入框设置下载的路径,一个button响应下载,一个进度条显示下载的进度;

具体代码如下:

xml的布局文件:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.anana.sockettest.DownActivity">    <TextView        android:id="@+id/textView"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentStart="true"        android:layout_alignParentTop="true"        android:text="要下载的资源的url:"        app:layout_constraintTop_toTopOf="parent"        tools:layout_editor_absoluteX="2dp"/>    <EditText        android:id="@+id/url"        android:layout_width="356dp"        android:layout_height="47dp"        android:layout_alignParentStart="true"        android:layout_below="@+id/textView"        android:layout_marginTop="12dp"        android:text="http://m.down.sandai.net/MobileThunder/Android_5.44.2.1966/thunder-5.44.2.5060-stable-release-OfficialSite_XunLeiProductCenter.apk"        tools:layout_editor_absoluteX="2dp"        tools:layout_editor_absoluteY="32dp"/>    <EditText        android:id="@+id/target"        android:layout_width="222dp"        android:layout_height="25dp"        android:layout_alignStart="@+id/download"        android:layout_below="@+id/textView2"        android:layout_marginTop="25dp"        android:text="/mnt/sdcard/"        tools:layout_editor_absoluteX="16dp"        tools:layout_editor_absoluteY="117dp"        android:layout_above="@+id/download"/>    <Button        android:id="@+id/download"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginStart="19dp"        android:text="下载"        tools:layout_editor_absoluteX="16dp"        tools:layout_editor_absoluteY="138dp"        android:layout_above="@+id/downbar"        android:layout_alignParentStart="true"/>    <ProgressBar        android:id="@+id/downbar"        style="?android:attr/progressBarStyleHorizontal"        android:layout_width="270dp"        android:layout_height="18dp"        android:layout_alignParentStart="true"        android:layout_centerVertical="true"        tools:layout_editor_absoluteX="16dp"        tools:layout_editor_absoluteY="204dp"/>    <TextView        android:id="@+id/textView2"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignEnd="@+id/download"        android:layout_alignStart="@+id/downbar"        android:layout_below="@+id/url"        android:layout_marginTop="18dp"        android:text="目标文件:"/></RelativeLayout>
activity主应用代码部分:

package com.anana.sockettest;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.ProgressBar;import com.anana.sockettest.util.DownUtil;import java.util.Timer;import java.util.TimerTask;public class DownActivity extends AppCompatActivity{    private EditText url, target;    private Button download;    private ProgressBar bar;    private Handler handler;    private int mDownStatu;    private DownUtil downUtil;    @Override    protected void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_down);        url = (EditText) findViewById(R.id.url);        target = (EditText) findViewById(R.id.target);        download = (Button) findViewById(R.id.download);        bar = (ProgressBar) findViewById(R.id.downbar);        handler = new Handler()        {            @Override            public void handleMessage(Message msg)            {                if (msg.what == 33)                {                    System.out.println("mDownStatu:"+mDownStatu);                    bar.setProgress(mDownStatu);                }                super.handleMessage(msg);            }        };        download.setOnClickListener(new View.OnClickListener()        {            @Override            public void onClick(View view)            {                downUtil = new DownUtil(url.getText().toString(), target.getText().toString(), 5);                new Thread()                {                    @Override                    public void run()                    {                        try                        {                            downUtil.download();                        }                        catch (Exception e)                        {                            e.printStackTrace();                        }                        final Timer timer = new Timer();                        timer.schedule(new TimerTask()                        {                            @Override                            public void run()                            {                                double completeRate = downUtil.getCompleteRate();                                mDownStatu = (int) (completeRate * 100);                                handler.sendEmptyMessage(33);                                if (mDownStatu >= 100)                                {                                    timer.cancel();                                }                            }                        }, 0, 1000);                    }                }.start();            }        });    }}

DownUtil类的编写,核心部分:

package com.anana.sockettest.util;import java.io.IOException;import java.io.InputStream;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.URL;/** * Created by wolfboyjiang on 2017/8/31. */public class DownUtil{    private String path;    private String targetFile;    private int threadnum;    private int fileSize;    private DownThread[] threads;    public DownUtil(String path, String targetFile, int threadnum)    {        this.path = path;        this.targetFile = targetFile;        this.threadnum = threadnum;        threads = new DownThread[threadnum];    }    public void download() throws Exception    {        System.out.println("download start ,url:"+path);        URL url = new URL(path);        HttpURLConnection conn = (HttpURLConnection) url.openConnection();        conn.setConnectTimeout(5000);        conn.setRequestMethod("GET");        //设置通用的请求属性        conn.setRequestProperty("Accept", "*/*");        conn.setRequestProperty("Accept-Language", "UTF-8");        conn.setRequestProperty("Connection", "Keep-Alive");//        conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT// 5.1; SV1)");        fileSize = conn.getContentLength();        conn.disconnect();        int currentPartSize = fileSize / threadnum + 1;        System.out.println("currentPartSize:"+currentPartSize+",currentPartSize:"+currentPartSize);        RandomAccessFile file = new RandomAccessFile(targetFile, "rw");        file.setLength(fileSize);        file.close();        for (int i = 0; i < threadnum; i++)        {            int startPos = i * currentPartSize;            RandomAccessFile currentPart = new RandomAccessFile(targetFile, "rw");            currentPart.seek(startPos);            threads[i] = new DownThread(startPos, currentPartSize, currentPart);            threads[i].start();        }    }    public double getCompleteRate()    {        int sumSize = 0;        for (int i = 0; i < threadnum; i++)        {            sumSize += threads[i].length;        }        System.out.println("fileSize:"+fileSize+",sumSize:"+sumSize);        return sumSize * 1.0 / fileSize;    }    private class DownThread extends Thread    {        private int startPos = 0;        private int currentPartSize;        private RandomAccessFile currentpart;        public int length = 0;        public DownThread(int startPos, int currentPartSize, RandomAccessFile currentpart)        {            this.startPos = startPos;            this.currentPartSize = currentPartSize;            this.currentpart = currentpart;        }        @Override        public void run()        {            try            {                URL url = new URL(path);                HttpURLConnection conn = (HttpURLConnection) url.openConnection();                conn.setConnectTimeout(5000);                conn.setRequestMethod("GET");                //设置通用的请求属性                conn.setRequestProperty("Accept", "*/*");                conn.setRequestProperty("Accept-Language", "UTF-8");                conn.setRequestProperty("Connection", "Keep-Alive");                InputStream in = conn.getInputStream();                skipFully(in,this.startPos);                byte[] buffer = new byte[1024];                int hasRead = 0;                while (length < currentPartSize && (hasRead = in.read(buffer)) > 0)                {                    currentpart.write(buffer,0,hasRead);                    length += hasRead;                }                currentpart.close();                in.close();            }            catch (Exception e)            {                e.printStackTrace();            }        }    }    public static void skipFully(InputStream in, long bytes) throws IOException    {        long remainning = bytes;        long len = 0;        while (remainning > 0)        {            len = in.skip(remainning);            remainning -= len;        }    }}




最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台