HttpURLConnection实现多线程下载资源contentLength()
2016-11-12 19:29
387 查看
package com.example.tyxiong.myapplication; import android.app.Activity; import android.app.ProgressDialog; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.widget.EditText; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.URL; import java.util.ArrayList; /* * * Android 网络应用. * 3句概述:1 Android支持JDK的TCP/IP UDP的网络通信API.即可用ServiceSocket Socket来建立基于TCP/IP协议的网络通信; * 也可以用DatagramSocket Dategrampacket MuliticastSocket来建立基于UDP协议的网络通信. * 2 Android支持JDK的URL URLConnection等网络通信. * 3 Android内置了HttpClient,方便的发送HTTP请求,简化了与网站间的交互.(可惜没有内置Web Service支持./有ksoap2-android项目) * * IP协议:实现计算机发送接收分组数据. * TCP协议:提供可靠无差错的通信服务. 端对端的协议(为两个通信实体之间通信起到了重要作用), 重发机制(接收方收到数据,有应答,若无则发送方重发数据) * TCP IP功能互补,通常两者结合使用,统称TCP/IP协议. * TCP/IP协议通信建立过程: 服务器端(主动)接收客户端连接请求(accept()方法),当有客户端(Socket)发送连接请求时, * 方法返回与之对应的Socket;通信链路建立.主客消失,可通过Socket通信. * 使用步骤4步: * 1 服务器端创建ServiceSocket对象,指定端口(大于1024) 默认IP * 2 对象的实例方法accept(),接收客户端请求.阻塞线程,有请求时方法返回Socket对象 * 3 客户端创建Socket对象,连接到指定的服务器端口 new Socket(remoteAddress,port) * 4 两个通信实体可通过Socket通信啦. 有方法getInputStream()/out.. 编码的问题linux平台用UTF-8字符集. * * 注意:android建立网络连接不允许在UI线程中进行. * 设置读取数据超时(BufferReader readLine()阻塞):Socket有方法setSoTimeout(),超时可抛异常 * 设置连接服务器超时:步骤1 建无连接的Socket new Socket() 2 connect()方法设置 * * 网络通信中多线程:服务器端:由于readLine()会阻塞线程,则每个Socket建立一个线程负责. * 客户端: 同样,需要一个线程读取服务器数据+ 然后主线程负责界面,用户输入. * * * URL,统一资源定位器,能打开URL指定网络数据的输入流(读取) 2个实例方法openStream()/打开连接的输入流 openURLConnection()/打开应用程序与URL资源间的连接对象 * URL组成:协议名,主机名,端口,资源. * 读取网络资源2步骤: * 1 创建URL对象 2openStream()打开资源输入流,,读取吧.>>> * * URLConnection提交请求:URL对象实例方法openURLConnection()方法->URLConnection对象-->发送请求,获取数据. * 6方法 2+4 设置请求头字段 setRequestProperty(key,value)设置请求字段的值. addRequestProperty()为指定key追加value值. * 获取响应 getContent()/获取该URLConnection内容 * getHeaderField(string)获取指定响应头字段的值 * getInputStream()/URLConnection输入流,读取响应 * getOutputStram()/URLConnection输出流,发送请求参数 * 使用分4步骤: * 1 URL对象,方法 获取URLConnection对象 * 2 设置URLConnection参数及请求字段属性 * 3 若发送GET请求,直接connect()方法建立实际连接. Post请求则要打开URLConnection的输出流,先发送请求参数. * 4 远程资源可用,用获取响应方法读取资源. * 注意:*****若既要发送请求,又要读取响应内容时,先发,再读.POST请求 * ****若需发送POST请求,必须设置 setDoOutput(true) setDoInput(true)头字段. * ****用完关闭流.try/catch/final * * HttpURLConnection URLConnection子类,增强,为Http访问提供了不4个便捷方法 * 1 getResponseCode()//获取服务器响应代码 * 2 getResponseMessage()//响应消息 * 3 getRequestMethod()//获取发送请求的方法 * 4 setRequestMethoe()//设置发送请求的方法. * * 多线程下载5步: * 1 URL对象 * 2 获取URL对象指定资源数据大小(getContentLength()) * 3 本地建立与资源相同大小空文件 * 4 平分资源计算每条线程下载的字节部分. * 5 创建,启动多条线程下载. * * * HttpClient :1概述:Apache组织的项目,Android也内置了HttpClient支持.简单的Http客户端,用于发送HTTP请求 * 接收响应,增强版本的HttpURLConnection.使用5步: 3个对象 3个方法 * 1 创建HttpClient对象 * 2 若发送GET请求--HttpGet对象 POST请求--HttpPost对象 * 3 设置发送请求参数,,,可用setParams()/setEntity() * 4 HttpClient对象execute()方法发送请求.该方法返回HttpResponse对象 * 5 HttpResponse对象 getEntity()方法,,获取响应内容. * * * * * * * HttpURLConnection URLConnection子类,增强,为Http访问提供了不4个便捷方法 * 1 getResponseCode()//获取服务器响应代码 * 2 getResponseMessage()//响应消息 * 3 getRequestMethod()//获取发送请求的方法 * 4 setRequestMethoe()//设置发送请求的方法. * */ public class MainActivity extends Activity { EditText show; Handler handler; private Thread thread; EditText fileName; EditText threadCount; ProgressDialog progressDialog; private int progress; private int MAX = 100; DownUtils downUtils; String url; String path; int count; public void send(View view) {//向服务器发送数据.... url = show.getText().toString(); path = fileName.getText().toString(); count = Integer.parseInt(threadCount.getText().toString().trim()); progressDialog.show(); thread.start(); }//发送GET请求... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); show = (EditText) findViewById(R.id.show); fileName = (EditText) findViewById(R.id.fileName); threadCount = (EditText) findViewById(R.id.count); progressDialog = new ProgressDialog(this); progressDialog.setTitle("下载"); progressDialog.setIndeterminate(false); progressDialog.setCancelable(false); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setMessage("正在下载..."); progressDialog.setMax(MAX); handler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 0x11) { progressDialog.setProgress(progress); } } }; thread = new Thread() { @Override public void run() { downUtils = new DownUtils(url, path, count); downUtils.sendGet(); while (progress < MAX) { float position = downUtils.getProgress(); progress = (int) (MAX * position); try { sleep(1 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } handler.sendEmptyMessage(0x11); } progressDialog.dismiss(); } }; } } class DownUtils { String link; /* "http://p.gdown.baidu.com/ab67d1f87dda5edd22d919fc5a33bad644220b671bb3bb17fd6f8849a61ed2c3c7e9c44f13348ef75f6bcbdb8cdc5c867bcf7dd31f353abeb47a285ab0b588c5c0df7dcdbcf395acd80b500258e99d064d92bac54af82bd95b7553bd86e2bc83ce217398cfb18bd8fd5e6a6f506db32f75cb5e965207230404b400a9fdd2fdc8e20c4215f9fde290e5b22eed14479ddd43a35e954f30c2e8ed119b7239a659fbf59390a45f51edaab818ef4eeb14a4011dd043f84f4b70f4d49f8a5b0571d5b1d8bdb84b2d49d3687d5b43e0fe513b59f3beef45c6121fd0088e20ad370cb22e02207716b95d8f627a5fe9d79f99b06852651f73c5d0e63476b8148506a88909fb0947b3e5510573632887aeee2e6b871dfe70d2ee93fc2fad2997f2a2845e1f40ac0b9ddbcf4e679cd8b0600f1a93af5774d530038d59a073d1e7f97ef1b488";*/ String path; int COUNT; public DownUtils(String link, String path, int COUNT) { this.link = link; this.path = "/mnt/sdcard/"+path; this.COUNT = COUNT; } ArrayList<DownThread> list = new ArrayList<>(); int fileSize = 0; int subSize = 0; public float getProgress() { int num = 0; for (int i = 0; i < list.size(); i++) { num += list.get(i).progress; } return 1.0f * num / fileSize; } public void sendGet() { RandomAccessFile file = null; try { final HttpURLConnection urlConnection; URL url = new URL(link); urlConnection = (HttpURLConnection) url.openConnection();//1获取与远程资源的连接. urlConnection.setConnectTimeout(10 * 1000); urlConnection.setRequestProperty("accept", "*/*"); urlConnection.setRequestProperty("connection", "Keep-Alive"); urlConnection.setRequestProperty("charset", "utf-8");//设置请求字段属性. urlConnection.getRequestMethod(); b41a urlConnection.setRequestMethod("GET"); //便捷方法设置发送请求方法 fileSize = urlConnection.getContentLength(); urlConnection.disconnect(); file = new RandomAccessFile(path, "rw"); file.setLength(fileSize); Log.w("xxx", "sendGet: 需要下载文件大小" + fileSize); subSize = fileSize / COUNT; for (int i = 0; i < COUNT; i++) { DownThread newThread = new DownThread(i * subSize, subSize);//// TODO: 11/11/2016 list.add(newThread); newThread.start(); } } catch (IOException e) { e.printStackTrace(); } finally { try { assert file != null; file.close(); } catch (IOException e) { e.printStackTrace(); } } } class DownThread extends Thread { public int position = 0; int length = 0; int progress = 0; public DownThread(int position, int length) { this.position = position; this.length = length; } @Override public void run() { HttpURLConnection urlConnection; URL url; try { RandomAccessFile randomAccessFile = new RandomAccessFile(path, "rw"); url = new URL(link); urlConnection = (HttpURLConnection) url.openConnection();//1获取与远程资源的连接. urlConnection.setConnectTimeout(10 * 1000); urlConnection.setRequestProperty("accept", "*/*"); urlConnection.setRequestProperty("connection", "Keep-Alive"); urlConnection.setRequestProperty("charset", "utf-8");//设置请求字段属性. urlConnection.getRequestMethod(); urlConnection.setRequestMethod("GET"); //便捷方法设置发送请求方法 urlConnection.connect(); InputStream inputStream = urlConnection.getInputStream(); long j = 0; while (j < position) { j += inputStream.skip(position - j); } randomAccessFile.seek(position); int read = 0; byte[] buffer = new byte[1024]; while (progress < length && read != -1) { read = inputStream.read(buffer, 0, buffer.length); randomAccessFile.write(buffer, 0, read); progress += read; } randomAccessFile.close(); inputStream.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (ProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } } <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.INTERNET" /> ![运行效果](http://img.blog.csdn.net/20161112192835504)
相关文章推荐
- Android 使用HttpURLConnection实现多线程下载 笔记
- HttpUrlConnection实现多线程下载网络资源
- Android-使用HttpURLConnection实现多线程下载
- HttpURLConnection实现多线程下载
- Android客户端请求服务端资源(HttpURLConnection和输入流实现)
- 使用HttpURLConnection实现多线程下载
- android HttpURLConnection实现多线程下载
- Android上Java网络资源访问(二)使用HttpURLConnection多线程下载
- android中使用HttpURLConnection实现多线程下载
- Android 使用HttpURLConnection 实现多线程下载
- 安卓基础:HttpURLConnection实现多线程下载
- Android开发_使用HttpURLConnection实现多线程下载
- 06_android入门_采用HttpURLConnection的POST方式实现登陆案例
- JAVA使用HttpUrlConnection实现自动上传文件
- 利用HttpURLConnection实现get,post方法发送信息
- 简单使用URLConnection、HttpURLConnection和HttpClient访问网络资源
- 04_android入门_采用HttpURLConnection的GET方式实现登陆案例
- 使用HttpURLConnection实现多线程下载
- android HttpURLConnection 实现下载
- HttpUrlConnection底层实现和关于java host绑定ip即时生效的设置及分析