Android基础总结(五)
HttpClient
发送get请求
创建一个客户端对象
HttpClient client = new DefaultHttpClient();
创建一个get请求对象
HttpGet hg = new HttpGet(path);
发送get请求,建立连接,返回响应头对象
HttpResponse hr = hc.execute(hg);
获取状态行对象,获取状态码,如果为200则说明请求成功
if(hr.getStatusLine().getStatusCode() == 200){
//拿到服务器返回的输入流
InputStream is = hr.getEntity().getContent();
String text = Utils.getTextFromStream(is);
}
发送post请求
//创建一个客户端对象
HttpClient client = new DefaultHttpClient();
//创建一个post请求对象
HttpPost hp = new HttpPost(path);
往post对象里放入要提交给服务器的数据
//要提交的数据以键值对的形式存在BasicNameValuePair对象中
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
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(); } }
发送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());
多线程下载
原理:服务器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){
for(int i = 0; i <= 3; i++){
File f = new File(i + ".txt");
f.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() + "%");
HttpUtils的使用
HttpUtils本身就支持多线程断点续传,使用起来非常的方便
创建HttpUtils对象
HttpUtils http = new HttpUtils();
下载文件
http.download(url, //下载请求的网址
target, //下载的数据保存路径和文件名
true, //是否开启断点续传
true, //如果服务器响应头中包含了文件名,那么下载完毕后自动重命名
new RequestCallBack<File>() {//侦听下载状态 //下载成功此方法调用
@Override
public void onSuccess(ResponseInfo<File> arg0) {
tv.setText("下载成功" + arg0.result.getPath());
} //下载失败此方法调用,比如文件已经下载、没有网络权限、文件访问不到,方法传入一个字符串参数告知失败原因
@Override
public void onFailure(HttpException arg0, String arg1) {
tv.setText("下载失败" + arg1);
} //在下载过程中不断的调用,用于刷新进度条
@Override
public void onLoading(long total, long current, boolean isUploading) {
super.onLoading(total, current, isUploading);
//设置进度条总长度
pb.setMax((int) total);
//设置进度条当前进度
pb.setProgress((int) current);
tv_progress.setText(current * 100 / total + "%");
}
});
Android基础总结(五)的更多相关文章
- android基础(五)网络数据解析方法
在网络上传输数据时最常用的方法有两种:XML和JSON,下面就对这两种类型的数据解析进行讲解. 一.XML数据解析 在Android中,常见的XML解析器分别为SAX解析器.DOM解析器和PULL解析 ...
- android基础(五)网络编程
android 的网络编程一般可以分为两种:基于Socket的,基于Http的. 一.socket与Http socket封装了TCP/IP协议,TPC/IP协议是传输层协议,主要解决数据如何在网络中 ...
- <Android 基础(五)> MVVM
介绍 MVVM,Model-View-ViewModel,与上次讲的MVP模式比较的类似,MVP中需要大量的接口文件,而MVVM模式下,View和ViewModel直接关联,使用上比较方便,简化了代码 ...
- 安卓Android基础第五天
使用HttpUrlConnection方式提交到服务器2 Get方式:组拼url地址把数据组拼到url上,有大小限制1kb(浏览器)或4kb(http协议) Post方式:post方式提交安全,没有大 ...
- Android基础夯实--重温动画(五)之属性动画 ObjectAnimator详解
只有一种真正的英雄主义 一.摘要 ObjectAnimator是ValueAnimator的子类,它和ValueAnimator一样,同样具有计算属性值的功能,但对比ValueAnimator,它会更 ...
- android基础---->JSON数据的解析
上篇博客,我们谈到了XML两种常用的解析技术,详细可以参见我的博客(android基础---->XMl数据的解析).网络传输另外一种数据格式JSON就是我们今天要讲的,它是比XML体积更小的数据 ...
- 基础4 Android基础
基础4 Android基础 1. Activity与Fragment的生命周期. Activity生命周期 打开应用 onCreate()->onStart()->onResume 按BA ...
- Android开发面试经——2.常见Android基础笔试题
标签: androidAndroid基础Android面试题Android笔试题 2015-03-12 15:04 3361人阅读 评论(3) 收藏 举报 分类: Android开发(29) 版 ...
- Android采访开发——2.通用Android基础笔试题
注意finddreams博客: http://blog.csdn.net/finddreams/article/details/44219231 正值跳槽的热季.整理一下Android面试中最常考的笔 ...
- Android For JNI(五)——C语言多级指针,结构体,联合体,枚举,自定义类型
Android For JNI(五)--C语言多级指针,结构体,联合体,枚举,自定义类型 我们的C已经渐渐的步入正轨了,基础过去之后,就是我们的NDK和JNI实战了 一.多级指针 指针的概念我们在前面 ...
随机推荐
- 使用SSH上传安装eclipse
安装eclipse 步骤: 1.上传eclipse tar文件 2.[root@localhost soft]# tar -zxvf eclipse-jee-galileo-SR2-linux-gtk ...
- php实现设计模式之 模板方法模式
<?php /** * 模板模式 * * 定义一个操作中的算法骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构可以定义该算法的某些特定步骤 * */ abstract class ...
- 高性能 TCP & UDP 通信框架 HP-Socket v3.5.1
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...
- zepto/jQuery、AngularJS、React、Nuclear的演化
写在前面 因为zepto.jQuery2.x.x和Nuclear都是为现代浏览器而出现,不兼容IE8,适合现代浏览器的web开发或者移动web/hybrid开发.每个框架类库被大量用户大规模使用都说明 ...
- RadioButton与CheckBox
笔者长期从事于数据库的开发,算了,不提当年了,因为一直用的是小语种(PowerBuilder),还是来说说这两个最常见的控件吧! RadioButton(单选)和CheckBox(多选) 先来看看继承 ...
- iOS开发--弹窗多选、单选框架
最近刚毕业...因为个毕设,都离职了又得重新找工作了,这是之前自己没事开直播写的一个小框架,后来各种趋于稳定后,简单的封装了下,写了个小demo,这里就不废话了,直接贴地址,也不编辑了,自己复制过去看 ...
- 会议管理心得记录(非markdown版)
前提 本文说的会议特指有开发团队成员参与的会议, 包括但不限于开发.设计.测试.运维.管理岗位的成员. 因为不同工种和行业都有其特殊性,我是一名程序员,并不太了解其他工种和行业的具体情况,不敢妄言. ...
- 如何做好一个Sprint Demo
我列出了一些关于如何做好一个Demo(演示)的建议.我想通过以下四个步骤可以做出一个较好的Demo. 第一步:准备Demo故事 以真实用户使用软件的方式进行Demo.关键点不在于演示软件如何工作,而是 ...
- ZooKeeper:数据模型
ZooKeeper数据模型 ZNode ZNode 分类 Stat Watcher Watcher工作原理 Watcher事件说明 Watcher注册 事件发布 示例 ZooKeeper 数据模型 整 ...
- [Hadoop in Action] 第1章 Hadoop简介
编写可扩展.分布式的数据密集型程序和基础知识 理解Hadoop和MapReduce 编写和运行一个基本的MapReduce程序 1.什么是Hadoop Hadoop是一个开源的框架,可编写和运 ...