A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 allen927 于 2015-11-9 09:23 编辑


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

android基础Day05(多线程下载)


(掌握)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




88 个回复

倒序浏览
很好很详细,赞一个
回复 使用道具 举报
顶一下顶一下
回复 使用道具 举报
长沙校区好火啊
回复 使用道具 举报
每日一顶
回复 使用道具 举报
顶基哥~~~~~~~~~~~长沙校区UP
回复 使用道具 举报
zhengsx 中级黑马 2015-11-16 22:45:21
7#
感觉深圳的帖子好少啊
回复 使用道具 举报
好流弊,佩服
回复 使用道具 举报
zqiang 中级黑马 2015-11-19 21:26:05
9#
不错,赞一个
回复 使用道具 举报
好牛掰  记得了!!!!!!!!!!!!!!!!!!!!!!!!!!!!
回复 使用道具 举报
先收藏了
回复 使用道具 举报
牛逼 顶顶顶顶顶顶顶顶顶顶
回复 使用道具 举报
感谢分享.....................
回复 使用道具 举报
支持支持支持  赞赞赞
回复 使用道具 举报
留着  以后有用!
回复 使用道具 举报
加油黑马
回复 使用道具 举报
文舞 中级黑马 2015-11-26 00:29:26
17#
长沙长沙长沙好
回复 使用道具 举报
相当好的资源!!
回复 使用道具 举报
好贴,必须赞赞赞~
回复 使用道具 举报
支持支持!
回复 使用道具 举报
12345下一页
您需要登录后才可以回帖 登录 | 加入黑马