Android 网络编程
HttpClient
发送get请求
创建一个客户端对象
HttpClient client = new DefaultHttpClient();
创建一个get请求对象
HttpGet hg = new HttpGet(path);
发送get请求,建立连接,返回响应头对象
HttpResponse hr = hc.execute(hg);
获取状态行对象,获取状态码,如果为200则说明请求成功
发送post请求
//创建一个客户端对象
HttpClient client = new DefaultHttpClient();
//创建一个post请求对象
HttpPost hp = new HttpPost(path);`- 往post对象里放入要提交给服务器的数据
//要提交的数据以键值对的形式存在BasicNameValuePair对象中
List parameters = new ArrayList();
BasicNameValuePair bnvp = new BasicNameValuePair("name", name);
BasicNameValuePair bnvp2 = new BasicNameValuePair("pass", pass);
parameters.add(bnvp);
parameters.add(bnvp2);
//创建实体对象,指定进行URL编码的码表
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters, "utf-8");
//为post请求设置实体
hp.setEntity(entity);异步HttpClient框架
发送get请求
//创建异步的httpclient对象
AsyncHttpClient ahc = new AsyncHttpClient();
//发送get请求
ahc.get(path, new MyHandler()); - 注意AsyncHttpResponseHandler两个方法的调用时机
class MyHandler extends AsyncHttpResponseHandler{
//http请求成功,返回码为200,系统回调此方法
@Override
public void onSuccess(int statusCode, Header[] headers,
//responseBody的内容就是服务器返回的数据
byte[] responseBody) {
Toast.makeText(MainActivity.this, new String(responseBody), 0).show();
}
//http请求失败,返回码不为200,系统回调此方法
@Override
public void onFailure(int statusCode, Header[] headers,
byte[] responseBody, Throwable error) {
Toast.makeText(MainActivity.this, "返回码不为200", 0).show();
}
} - 把要提交的数据封装在rp对象中,就不用像前面的get请求一样去拼接对象
RequestParams rp = new RequestParams();
rp.put("name", name);
rp.put("pass", pass);发送post请求
- 使用RequestParams对象封装要携带的数据
//创建异步httpclient对象
AsyncHttpClient ahc = new AsyncHttpClient();
//创建RequestParams封装要携带的数据
RequestParams rp = new RequestParams();
rp.add("name", name);
rp.add("pass", pass);
//发送post请求
ahc.post(path, rp, new MyHandler());多线程下载
多线程:快
* 原理:抢占服务器资源
* 单线程下载:线程从第0个字节开始下,下到最后一个字节,在本地硬盘的临时文件中从第0个字节开始写,写到最后一个字节,下载完成时,临时文件也写完了,本地就创建了一个与服务器文件一模一样的文件
- 多线程下载:每条线程下载的开始位置和结束位置都是不一样的,每条线程下载的数据合在一起才是服务器的完整的文件
多线程的每个线程给一个ID
每个线程的下载区间:size=总的字节数/线程数
每个线程的开始位置:id*size
每个线程的结束位置:(id+1)*size-1最后一个线程的结束位置:总长度-1
- 多线程下载:每条线程下载的开始位置和结束位置都是不一样的,每条线程下载的数据合在一起才是服务器的完整的文件
- 断点续传:从上次下载结束的位置下载
原理:每次下载把下载进度保存至一个文本临时文件中,下一次下载时从文本临时文件获取上一次下载的进度,从这个进度开始继续下载
> 原理:服务器CPU分配给每条线程的时间片相同,服务器带宽平均分配给每条线程,所以客户端开启的线程越多,就能抢占到更多的服务器资源
确定每条线程下载多少数据
- 发送http请求至下载地址
String path = "http://192.168.1.102:8080/editplus.exe"; URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000);
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET"); - 获取文件总长度,然后创建长度一致的临时文件
if(conn.getResponseCode() == 200){
//获得服务器流中数据的长度
int length = conn.getContentLength();
//创建一个临时文件存储下载的数据
RandomAccessFile raf = new RandomAccessFile(getFileName(path), "rwd");
//设置临时文件的大小
raf.setLength(length);
raf.close(); - 确定线程下载多少数据
//计算每个线程下载多少数据
int blockSize = length / THREAD_COUNT;计算每条线程下载数据的开始位置和结束位置
for(int id = 1; id <= 3; id++){
//计算每个线程下载数据的开始位置和结束位置
int startIndex = (id - 1) * blockSize;
int endIndex = id * blockSize - 1;
if(id == THREAD_COUNT){
endIndex = length;
}
//开启线程,按照计算出来的开始结束位置开始下载数据
new DownLoadThread(startIndex, endIndex, id).start();
}再次发送请求至下载地址,请求开始位置至结束位置的数据
String path = "http://192.168.1.102:8080/editplus.exe"; URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000);
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
//向服务器请求部分数据
conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);
conn.connect(); - 下载请求到的数据,存放至临时文件中
if(conn.getResponseCode() == 206){InputStream is = conn.getInputStream();
RandomAccessFile raf = new RandomAccessFile(getFileName(path),"rwd");//指定从哪个位置开始存放数据
raf.seek(startIndex);
>byte[] b = new byte[1024];
int len;
while((len = is.read(b)) != -1){
raf.write(b, 0, len);
}
raf.close();}
带断点续传的多线程下载
- 定义一个int变量记录每条线程下载的数据总长度,然后加上该线程的下载开始位置,得到的结果就是下次下载时,该线程的开始位置,把得到的结果存入缓存文件
//用来记录当前线程总的下载长度
int total = 0;
while((len = is.read(b)) != -1){
raf.write(b, 0, len);
total += len;
//每次下载都把新的下载位置写入缓存文本文件
RandomAccessFile raf2 = new RandomAccessFile(threadId + ".txt", "rwd");
raf2.write((startIndex + total + "").getBytes());
raf2.close();
} - 下次下载开始时,先读取缓存文件中的值,得到的值就是该线程新的开始位置
FileInputStream fis = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String text = br.readLine();
int newStartIndex = Integer.parseInt(text);
//把读到的值作为新的开始位置
startIndex = newStartIndex;
fis.close(); - 三条线程都下载完毕之后,删除缓存文件
RUNNING_THREAD--;
if(RUNNING_THREAD == 0){<span class="hljs-keyword">for(<span class="hljs-keyword">int i = <span class="hljs-number">0; i <= <span class="hljs-number">3; i++){
<span class="hljs-keyword">File f = <span class="hljs-keyword">new <span class="hljs-keyword">File(i + <span class="hljs-string">".txt");
f.<span class="hljs-keyword">delete();
}}
手机版的断点续传多线程下载器
- 把刚才的代码直接粘贴过来就能用,记得在访问文件时的路径要改成Android的目录,添加访问网络和外部存储的路径
用进度条显示下载进度(掌握)
- 拿到下载文件总长度时,设置进度条的最大值
//设置进度条的最大值
pb.setMax(length); - 进度条需要显示三条线程的整体下载进度,所以三条线程每下载一次,就要把新下载的长度加入进度条
定义一个int全局变量,记录三条线程的总下载长度`
int progress;
刷新进度条
while((len = is.read(b)) != -1){
raf.write(b, 0, len);//把当前线程本次下载的长度加到进度条里
progress += len;
pb.setProgress(progress); - 每次断点下载时,从新的开始位置开始下载,进度条也要从新的位置开始显示,在读取缓存文件获取新的下载开始位置时,也要处理进度条进度
FileInputStream fis = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String text = br.readLine();
int newStartIndex = Integer.parseInt(text);
//新开始位置减去原本的开始位置,得到已经下载的数据长度
int alreadyDownload = newStartIndex - startIndex;
//把已经下载的长度设置入进度条
progress += alreadyDownload;添加文本框显示百分比进度
tv.setText(progress * 100 / pb.getMax() + "%");
Android 网络编程的更多相关文章
- Android网络编程只局域网传输文件
Android网络编程之局域网传输文件: 首先创建一个socket管理类,该类是传输文件的核心类,主要用来发送文件和接收文件 具体代码如下: package com.jiao.filesend; im ...
- Android网络编程基础
Android网络编程只TCP通信 TCP 服务器端工作的主要步骤如下.步骤1 调用ServerSocket(int port)创建一个ServerSocket,并绑定到指定端口上.步骤2 调用acc ...
- Android网络编程系列 一 TCP/IP协议族
在学习和使用Android网路编程时,我们接触的仅仅是上层协议和接口如Apache的httpclient或者Android自带的httpURlconnection等等.对于这些接口的底层实现我们也有必 ...
- Android网络编程系列 一 Socket抽象层
在<Android网络编程>系列文章中,前面已经将Java的通信底层大致的描述了,在我们了解了TCP/IP通信族架构及其原理,接下来我们就开始来了解基于tcp/ip协议层的Socket抽 ...
- Android 网络编程 Socket
1.服务端开发 创建一个Java程序 public class MyServer { // 定义保存所有的Socket,与客户端建立连接得到一个Socket public static List< ...
- Android网络编程概述
Android网络编程概述 首先,应该了解的几个问题: 1)Android平台网络相关API接口 a) java.net.*(标准Java接口) java.net.*提供与联网有关的类,包括流.数据包 ...
- Android网络编程http派/申请服务
最近的研究Android网络编程知识,这里有一些想法,今晚学习.与您分享. 在实际的应用程序的开发非常需要时间appserver请求数据,那么app怎样发送请求呢?以下的代码就是当中的一种情况.使用H ...
- 转 Android网络编程之使用HttpClient批量上传文件 MultipartEntityBuilder
请尊重他人的劳动成果,转载请注明出处:Android网络编程之使用HttpClient批量上传文件 http://www.tuicool.com/articles/Y7reYb 我曾在<Andr ...
- Android网络编程要学的东西与Http协议学习
本节引言: 本节开始我们来学习Android网络编程相关的一些东西:Android端网络编程是要干嘛?http协议的学习,使用自带扣脚Json解析类解析Json,XML解析常用的几种方式,HttpUr ...
- 【Android 应用开发】Android 网络编程 API笔记 - java.net 包 权限 地址 套接字 相关类 简介
Android 网络编程相关的包 : 9 包, 20 接口, 103 类, 6 枚举, 14异常; -- Java包 : java.net 包 (6接口, 34类, 2枚举, 12异常); -- An ...
随机推荐
- OpenCV 之 支持向量机 (一)
机器学习是由 模型 + 策略 + 算法 构成的,构建一种机器学习方法 (例如,支持向量机),就是具体去确定这三个要素. 1 支持向量机 支持向量机,简称 SVM (Support Vector Ma ...
- ACM失败之路
校赛打完,已过四月,该是准备背起行囊,踏上考研之路了,自然,得先阔别一下ACM了,想起这几年ACM路,感慨颇多,不得不一诉心肠,与大家分享一下我的ACM历程,如果有人能从此文获取一些益处,那我就很欣慰 ...
- linux常用指令
整理下来的linux常用指令 mount [-t 文件系统] 设备文件名 挂载点挂载命令,一般用于在挂载ISO,或者其他比如U盘等设备时使用,[-t iso9660]为固定格式,可写可不写,非必写项. ...
- 搭建一套自己实用的.net架构(1)【概述】
入园很久,一直默默的潜水,近来得空想写点什么. 思前想后,那就把自己平时没事干自己摘抄.引用.瞎写的一些东西写出来.帮助自己巩固一下,顺便请高手们指点一二. 我本人很懒 ,一些代码就是直接复制别人的劳 ...
- vs2015 安装之后安装MSSM 2016 导致 vs启动报错 System.ArgumentException 已添加了具有相同键的项,ActivityLog.xml
如题,先是装了vs2015,开发什么的都没有问题,后来安装了SqlServer2016 MSSM,出大问题了,vs2015打开就报错,具体错误如上,还想还有个ActivityLog.xml 这个文件的 ...
- Spring自动注入properties文件
实现spring 自动注入属性文件中的key-value. 1.在applicationContext.xml配置文件中,引入<util />命名空间. xmlns:util=" ...
- 关于DOS与cmd(windows系统)
dos是计算机的最初期的操作系统,对电脑操作必须输入各种dos命令窗口,可以理解成运行计算机机器内部语言,知道编程吗?其实早期dos命令操作系统就是运行计算机内部的编程命令,因此操作人员都必须具有一定 ...
- 关于把.net 2.0的项目升级到.net4.0遇到的一些问题
进入公司实习的的第一个项目又是是一个升级项目.这次升级的是一个c/s架构的项目. 大致介绍一下这个项目的结构客户端采用winform+devexpress商业控件开发的,数据库是用的oracle数据库 ...
- Windows phone应用开发[19]-RSA数据加密
在这个系列的第十六章节中Windows phone应用开发[16]-数据加密 中曾详细讲解过windows phone 常用的MD5,HMAC_MD5,DES,TripleDES[3DES] 数据加密 ...
- java画图之曲线拖动
目标:在窗体上按下鼠标按键.然后拖动鼠标,在按下和拖动之间绘制曲线 事件机制 事件源对象:窗体 事件监听方法:addMouseListener(MouseListener l);addMouseMot ...