黑马程序员技术交流社区

标题: 【长沙校区】十年磨一剑【基哥笔记】Android基础Day05(下载) [打印本页]

作者: allen927    时间: 2015-11-9 09:15
标题: 【长沙校区】十年磨一剑【基哥笔记】Android基础Day05(下载)
本帖最后由 allen927 于 2015-11-9 09:23 编辑


同样的课程、老师、就业,更好的学习环境,更低的学习成本!
内地学员,选择长沙校区,靠谱!!!
报名热线:0731-85833115
  QQ  : 2355535415

android基础Day05(多线程下载)

资源总连接:http://bbs.itheima.com/thread-249703-1-1.html

(掌握)httpclientgetpost
HttpClient:他是android集成的一个三方框架 Http框架
HttpClientURL  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;
        }

(掌握)getpost提交数据的中文乱码处理
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框架 (智能北京)




下载资源

Doc笔记
课程视频代码

希望大家积极转发、分享,让更多的人轻松学习!
相关链接:
长沙中心--黑马双元课堂JAVA入学辅导班1期火爆开班啦!!!
长沙黑马程序员学习激情无限“吊炸天”
黑马程序员长沙校区生活圈,60秒搞定吃住学
http://bbs.itheima.com/thread-243108-1-1.html





作者: 邓娇林    时间: 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