黑马程序员技术交流社区
标题: 【长沙校区】十年磨一剑【基哥笔记】Android基础Day05(下载) [打印本页]
作者: allen927 时间: 2015-11-9 09:15
标题: 【长沙校区】十年磨一剑【基哥笔记】Android基础Day05(下载)
本帖最后由 allen927 于 2015-11-9 09:23 编辑
同样的课程、老师、就业,更好的学习环境,更低的学习成本!
android基础Day05(多线程下载)
•(掌握)httpclient的get和postHttpClient:他是android集成的一个三方框架 Http框架
HttpClient在URL HttpClient再次进行了oop的封装
HttpClient:他就是一个浏览器
执行请求 回送响应
HttpClient:浏览器 方法:执行 响应 HttpReponse exeucute(请求HttpUriRequest)
/** * 使用HttpClient框架 以GET请求提交数据到服务器
* @param map 数据
* @param path 请求路径
* @return
* @throws Exception
*/
publicstatic boolean doHttpClientGet(Map<String, String> map, String path)throws Exception{
//特点:http://localhost:8080/web/LoginServlet?name=itcast&pwd=234
//拼接uri
StringBuffersb = new StringBuffer(path);
sb.append("?");
for(Map.Entry<String,String> entry:map.entrySet()){
Stringkey = entry.getKey();
Stringvalue = entry.getValue();
sb.append(key).append("=").append(value);
sb.append("&");
}
//删除最后一个&
sb.deleteCharAt(sb.length()-1);
//浏览器
HttpClient httpClient = new DefaultHttpClient();
//get请求对象
HttpGet request = new HttpGet(sb.toString());
//执行请求
HttpResponse response = httpClient.execute(request);
//判断响应码是否为200
if(response.getStatusLine().getStatusCode() == 200){
//获取服务器回送的流
InputStream inputStream =response.getEntity().getContent();
//返回 success or error
Stringcontent = changeStreamToString(inputStream);
if("success".equals(content)){
returntrue;
}else{
returnfalse;
}
}
returnfalse;
}
post请求
/**
* 使用HttpClient框架 以POST请求提交数据到服务器
* @param map 数据
* @param path 请求路径
* @return
* @throws Exception
*/
publicstatic boolean doHttpClientPost(Map<String, String> map, String path) throwsException{
//post请求:请求实体
HttpClientclient = new DefaultHttpClient();//浏览器
HttpPostrequest = new HttpPost(path);//post请求对象
//实体参数
List<NameValuePair>parameters = new ArrayList<NameValuePair>();
for(Map.Entry<String,String> entry:map.entrySet()){
Stringname = entry.getKey();
Stringvalue = entry.getValue();
NameValuePairnvp = new BasicNameValuePair(name, value);
parameters.add(nvp);
}
//实体
UrlEncodedFormEntityentity = new UrlEncodedFormEntity(parameters, "utf-8");
//把实体设置给请求对象
request.setEntity(entity);
//执行请求
HttpResponseresponse = client.execute(request);
//判断响应码是否为200
if(response.getStatusLine().getStatusCode()== 200){
//获取服务器回送的流
InputStreaminputStream = response.getEntity().getContent();
//返回 success or error
Stringcontent = changeStreamToString(inputStream);
if("success".equals(content)){
returntrue;
}else{
returnfalse;
}
}
returnfalse;
}
•(掌握)get、post提交数据的中文乱码处理
get请求
浏览器进行URL编码
服务器:
中文乱码问题:
浏览器:UTF-8
服务器:tomcat ISO-8859-1
使用HttpClient框架是不会乱码。
那么HttpClient使用的编码:UTF-8
•(了解)asyncHttpClient的使用asyncHttpClient
async:异步 开了一个线程
HttpClient:使用Http协议的客户端
他对HttpClient进行了封装:
Thread + HttpClient
不用再开线程。
把AsyncHttpClient的源码添加到工程
•(掌握)文件上传1 把服务上调试通过
文件上传:业务操作 也要使用开源项目 FileUpload
2 客户端
•(掌握)文件下载
原理:
请求服务器的资源,服务器回送该文件的文件流,把流保存在android手机的sdcard.
public class MainActivity extends Activity{
publicstatic final int SUCCESS_LOAD_DATA = 0;
privateImageView iv;
privateButton bt_set;
privateFile file;
privateHandler mHandler = new Handler(){
publicvoid handleMessage(android.os.Message msg) {
switch(msg.what) {
caseSUCCESS_LOAD_DATA:
Uriuri = (Uri) msg.obj;
iv.setImageURI(uri);
//图片下载成功
//设置按钮可用
bt_set.setEnabled(true);
break;
default:
break;
}
};
};
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv= (ImageView) findViewById(R.id.iv);
bt_set= (Button) findViewById(R.id.bt_set);
}
publicvoid download(View v){
//
从服务器上下载图片 //使用api: Thread 权限 HttpClient Environment
//目的:把图片下载到sdcard
newThread(new MyTask()).start();
}
privateclass MyTask implements Runnable{
//下载图片
@Override
publicvoid run() {
Stringpath = "http://10.0.2.2:8080/08web/tokhot4.JPG";
try{
//客户端
HttpClientclient = new DefaultHttpClient();
//请求对象
HttpGetrequest = new HttpGet(path);
//执行请求 获取响应对象
HttpResponseresponse = client.execute(request);
//判断响应是否成功
if(response.getStatusLine().getStatusCode()== 200){
//获取服务器回送的流
InputStreaminputStream = response.getEntity().getContent();
//把流保存成文件
Stringname = getFileName(path);
file= new File(Environment.getExternalStorageDirectory(),name);
FileOutputStreamfos = new FileOutputStream(file);
byte[]buffer = new byte[1024];
intlen = 0;
while((len= inputStream.read(buffer)) != -1){
fos.write(buffer,0, len);
}
fos.close();
inputStream.close();
//显示图片
Uriuri = Uri.fromFile(file);//获取文件的uri
Messagemsg = Message.obtain(mHandler, SUCCESS_LOAD_DATA, uri);
msg.sendToTarget();
}else{
alertUser("下载失败");
}
}catch (Exception e) {
e.printStackTrace();
alertUser("下载失败");
}
}
}
publicvoid set(View v){
newThread(){
publicvoid run() {
try{
/*//设置墙纸
Drawabledrawable = iv.getDrawable();
//请求问Drawable如何转换成bitmap
*/
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
setWallpaper(bitmap);//设置墙纸是一个耗时的操作 开线程
alertUser("设置成");
}catch (Exception e) {
e.printStackTrace();
alertUser("设置失败");
}
};
}.start();
}
/**
* 根据网络路径获取文件名称
* @param path
* @return
*/
privateString getFileName(String path){
returnpath.substring(path.lastIndexOf("/")+1);
}
privatevoid alertUser(final String text){
runOnUiThread(newRunnable() {
@Override
publicvoid run() {
Toast.makeText(getApplicationContext(),text, 0).show();
}
});
}
/**
* 把Drawable转换成Bitmap
* @param drawable
* @return
*/
publicstatic Bitmap drawableToBitmap(Drawable drawable) {
if (null == drawable) {
return null;
}
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Config config = (drawable.getOpacity() != PixelFormat.OPAQUE) ?Config.ARGB_8888
: Config.RGB_565;
Bitmap bitmap = null;
try {
bitmap = Bitmap.createBitmap(width, height, config);
} catch (OutOfMemoryError e) {
}
if (null != bitmap) {
Rect oldRect = drawable.getBounds();
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, width,height);
drawable.draw(canvas);
drawable.setBounds(oldRect);
}
return bitmap;
}
}
•(掌握)多线程下载的原理多线程下载比单线程下载:速度更快
为什么?
多条线程可以增加服务器的带宽。 服务器那边的响应对象变多
抢占服务器的资源变多。
未知:
1 文件的大小
联网获取文件的大小,只需要服务器告诉我文件的大小,不需要文件流
只要响应的头信息:
2 请求服务器指定范围的数据
Http协议他可以指定范围:
key:Range value:bytes:start-end
3 把服务返回的数据正确的写入到指定的位置
RandomAccessFile 随机访问文件
•(掌握)android多线程下载获取服务器上文件的大小
在客户创建和服务器大小一样的文件
计算block每条线程的下载量
开启三条线程下载
下载线程
/**
* 下载线程的参数:
* 下载的资源 path
* 每条线程的下载量block
* 下载线程的id threadid
* 下载文件的存放位置 file
* 可以通过:block threadid 计算出开始位置 和结束位置
*
*/
privateclass DownloadThread extends Thread{
privateString path;
privateint block;
privateint threadid;
privateFile file;
privateint start;//开始位置
privateint end;//结束位置
publicDownloadThread(String path, int block, int threadid, File file) {
super();
this.path= path;
this.block= block;
this.threadid= threadid;
this.file= file;
//计算下载线程的开始位置和结束位置
start = threadid*block;
end = (threadid + 1)*block - 1;
}
@Override
publicvoid run() {
super.run();
try{
//执行分段下载
HttpClientclient = new DefaultHttpClient();
HttpGet request = new HttpGet(path);
//设置下载的范围
request.addHeader("Range","bytes:"+start+"-"+end);
HttpResponseresponse = client.execute(request);
//分段下载服务器的响应码是:206
if(response.getStatusLine().getStatusCode()== 206){
InputStreaminputStream = response.getEntity().getContent();
RandomAccessFile raf = new RandomAccessFile(file,"rwd");
//跳转到要写入的位置
raf.seek(start);
//把数据写入到文件
byte[]buffer = new byte[1024];
intlen = 0;
while((len= inputStream.read(buffer)) != -1){
raf.write(buffer, 0, len);
}
raf.close();
inputStream.close();
Log.i(TAG,"第"+threadid+"线程下载完成");
}
}catch (Exception e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
}
•(掌握)android多线程下载 出现下载进度条进度条 操作:
1 设置最大值 setMax(filelength);
2 更新进度 setProgress()
下载百分比 操作
1 更新 setText("") 根据 最大值 和 当前的下载量的对比
Handler + Message来实现
•(掌握)android多线程断点下载暂停下载
1 点击下载按钮状态的切换
2 暂停
控制3条下载的子线程:让三条线程都停止下载
3 继续下载
记录原来每条线程的下载量。文件来记录
规范:0.txt
4 点击继续下载
你们在敲这个项目的时候,用两个按钮。
•(了解)开源项目多线程断点下载Afinal框架 是一个中国人整合一些国外的框架。 一行搞定所有的事情
Afinal 框架 升级到了Xutils框架 (智能北京)
下载资源
希望大家积极转发、分享,让更多的人轻松学习! 相关链接:
长沙中心--黑马双元课堂JAVA入学辅导班1期火爆开班啦!!!
长沙黑马程序员学习激情无限“吊炸天”
作者: 邓娇林 时间: 2015-11-9 16:41
很好很详细,赞一个
作者: 784080960 时间: 2015-11-11 18:52
顶一下顶一下
作者: 梦我天堂 时间: 2015-11-11 23:09
长沙校区好火啊
作者: 微笑、守望 时间: 2015-11-14 22:37
每日一顶
作者: 秋色潇湘 时间: 2015-11-14 22:47
顶基哥~~~~~~~~~~~长沙校区UP
作者: zhengsx 时间: 2015-11-16 22:45
感觉深圳的帖子好少啊
作者: 過眼焱雲シ 时间: 2015-11-18 23:30
好流弊,佩服
作者: zqiang 时间: 2015-11-19 21:26
不错,赞一个
作者: 超级宝贝乐爷 时间: 2015-11-20 23:08
好牛掰 记得了!!!!!!!!!!!!!!!!!!!!!!!!!!!!
作者: 欧欧拐 时间: 2015-11-21 00:06
先收藏了
作者: zhangguohui 时间: 2015-11-21 20:11
牛逼 顶顶顶顶顶顶顶顶顶顶
作者: 半指流沙 时间: 2015-11-21 20:49
感谢分享.....................
作者: Mr.Ar.Rn 时间: 2015-11-23 20:24
支持支持支持 赞赞赞
作者: 杨凯瑞 时间: 2015-11-23 21:41
留着 以后有用!
作者: 13533258481 时间: 2015-11-25 23:56
加油黑马
作者: 文舞 时间: 2015-11-26 00:29
长沙长沙长沙好
作者: JadynAi 时间: 2015-11-26 20:59
相当好的资源!!
作者: 队长别开枪是我 时间: 2015-11-26 21:17
好贴,必须赞赞赞~
作者: 月夜飘星 时间: 2015-11-29 18:10
支持支持!
作者: 845479430 时间: 2015-11-29 21:56
基哥谢谢你了,你的大礼我收下了
作者: 三生石123 时间: 2015-11-29 23:06
加油 一起加油
作者: Xiiian 时间: 2015-11-30 21:37
作者: gawain 时间: 2015-12-1 22:41
66666666666666666666666
作者: 队长别开枪是我 时间: 2015-12-2 23:33
说的好 支持一下~
作者: 845479430 时间: 2015-12-3 19:19
顶基哥~~~~~~~~~~~长沙校区UP
作者: Makise_Kurisu 时间: 2015-12-4 00:07
路过看下,顶一个!!!~~
作者: 啊戴哥 时间: 2015-12-5 14:41
真的是太完美了 啊哈哈 的
作者: Endless_paradox 时间: 2015-12-7 13:00
先收藏了
作者: 阳光下的枫叶 时间: 2015-12-8 23:42
好东西,留下来!!!!
作者: xuao277457401 时间: 2015-12-11 23:28
实在是太屌了~~~
作者: 1312564637 时间: 2015-12-12 09:36
赞……
作者: hmjava520 时间: 2015-12-12 17:50
新手表示看不懂
作者: 小欢 时间: 2015-12-12 22:48
基哥辛苦了,多谢分享
作者: 744919632 时间: 2015-12-13 00:36
基哥威武。赞赞赞!
作者: 柯平常 时间: 2015-12-13 19:18
基哥威武!!!!!!
作者: wwwjpm@126.com 时间: 2015-12-13 22:05
先收着,回头学习多线程再仔细看看
作者: 孤独成瘾 时间: 2015-12-14 21:36
66666666666!!!
作者: labozx 时间: 2015-12-15 21:26
加油,赞赞赞赞赞赞攒攒
作者: 备战 时间: 2015-12-15 22:58
赞赞赞,黑马很吊了。
作者: zcbcba123 时间: 2015-12-16 11:28
好东西好多~
作者: 唐洪超 时间: 2015-12-16 11:32
很细制,不错
作者: 子午鼬 时间: 2015-12-16 22:31
太难了,我怎么不懂呀
作者: 孤独成瘾 时间: 2015-12-17 18:43
加油,加油,加油
作者: DaYe 时间: 2015-12-18 21:49
好贴需要顶赞一个
作者: 洋葱头头 时间: 2015-12-18 21:56
才学了一年呢
作者: ToSina 时间: 2015-12-18 23:49
加油 加油 加油
作者: wangyoucao 时间: 2015-12-19 21:13
谢谢分享。。。。
作者: 孤独成瘾 时间: 2015-12-19 21:27
不错,不错,真的很不错
作者: icm 时间: 2015-12-21 12:30
come on~
作者: 1050498188 时间: 2015-12-21 20:46
支持支持支持支持支持支持支持
作者: bowllboy 时间: 2015-12-22 23:47
新手,过来围观
作者: 很急很关键 时间: 2015-12-23 17:36
好牛逼 顶一下
作者: 孤独成瘾 时间: 2015-12-23 21:34
好历害,赞一下,666,真不错
作者: 暴走的斯温 时间: 2015-12-23 23:06
暂时离我还很遥远, 只是进来先膜拜 膜拜一下
作者: yipiao 时间: 2015-12-23 23:11
老师都很负责!很努力!希望我们都能学好.学精
作者: wangmiaosen 时间: 2015-12-26 22:45
基哥很厉害,不明觉厉
作者: peiyanda 时间: 2015-12-26 22:58
写的好,必须赞!!
作者: 注意背后 时间: 2015-12-26 23:44
牛逼...门外汉福利帖
作者: 谢光智 时间: 2015-12-27 19:37
赞一个!!!
作者: jauliun 时间: 2015-12-28 23:54
牛逼是一境界!
作者: houbofly 时间: 2015-12-30 12:15
给力,相当不错
作者: yellowbee 时间: 2015-12-31 22:22
好贴,我找了很久,我顶。
作者: 1050498188 时间: 2016-1-1 00:11
支持支持支持支持支持支持支持
作者: jauliun 时间: 2016-1-3 22:52
赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞
作者: mmxcf1 时间: 2016-1-4 11:08
wo jiu kan kankan
作者: zhou402981948 时间: 2016-1-6 19:34
顶顶顶顶顶顶顶顶顶顶顶顶顶顶
作者: 韦丹艳58 时间: 2016-1-6 22:22
一万个赞!!!!!!!!!!!!!!!!!!!!!!!
作者: 韦丹艳58 时间: 2016-1-6 22:24
一万个赞!!!!!!!!!!!!!!!!!!!!!!!
作者: 122347 时间: 2016-1-8 13:29
不错,不错,真有心,谢谢了
作者: 超级小鱼 时间: 2016-1-16 22:54
好东西,顶一个
作者: 悠悠天下 时间: 2016-1-17 22:08
谢谢,学习了
作者: black习 时间: 2016-1-18 23:26
厉害啊1111
作者: 夕兮兮 时间: 2016-1-20 12:01
感谢分享
作者: 夕兮兮 时间: 2016-1-20 12:01
感谢分享
作者: 悠悠天下 时间: 2016-1-20 21:46
学习学习
作者: 328253905 时间: 2016-1-21 18:18
{:2_35:}{:2_36:}
作者: 执笔写毛头 时间: 2016-1-24 22:42
写的不错 我顶顶顶顶顶
作者: 冷色 时间: 2016-1-26 00:07
谢谢分享
作者: 西贝 时间: 2016-1-28 09:28
不知跟北京的讲义一样不
作者: 奋斗小白1 时间: 2016-1-30 23:42
赞一个顶起来
作者: C.罗纳尔多 时间: 2016-2-2 22:43
收了,收了。多谢{:2_31:}
作者: a527512132 时间: 2016-2-4 20:57
悄悄的带走,
作者: 星空仰望heaven 时间: 2016-2-7 12:27
非常好!!!
作者: 菇凉斋 时间: 2016-4-1 00:19
讲解的很细,可以消化,谢谢sa
作者: 菇凉斋 时间: 2016-4-1 00:21
知识点划分很细,重点一目了然.......感谢分享
作者: 123liu123 时间: 2016-4-1 22:47
很实用,赞一个......
作者: 菇凉斋 时间: 2016-4-2 23:09
顶一个,谢基哥分享.......
作者: 蒂尔 时间: 2016-4-17 15:04
谢谢分享
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |