Android学习笔记 day05 _ 网络编程2

Android学习笔记 day05 _ 网络编程2


一、 获取服务器数据时乱码问题解决

  1. 乱码原因:

    Android客户端在服务器取数据时编码与服务器编码不一样,因此我们要让客户端和服务器
    两端的字符集编码保持一致,通常采用UTF-8编码
    
  2. 解决办法:

    1. 修改Android客户端编码:
        使用URLEncoder.encode(name,"UTF-8")进行url编码:
            String path = "http://192.168.22.136:8080/web/servlet/LoginServlet?username="+URLEncoder.encode(name,"UTF-8")+"&password="+URLEncoder.encode(pwd,"UTF-8");
    2. 修改服务器编码: 
    

二、 第二种向服务器获取数据方式:HttpClient

  1. GET方式执行过程:

                // 1. 创建一个url对象 参数就是网址
                String path = "http://192.168.1.102/web/servlet/LoginServlet?username="
                        + name + "&password=" + pwd;
    
                // (1) 初始化HttpClient对象
                HttpClient client = new DefaultHttpClient();
                // (2) 创建一个get请求
                HttpGet get = new HttpGet(path);
                // (3) 执行一个get请求
                HttpResponse response = client.execute(get);
                // (4) 返回请求状态码
                int code = response.getStatusLine().getStatusCode();
    
                if (code == 200) {
                    // 6. 获取服务器给我们返回的数据
                    InputStream in = response.getEntity().getContent();
                    // 7. 处理结果
                    final String content = StreamUtils.readStream(in);
                    // 8. //更新UI界面
                    showToast(content);
                }
    
  2. POST方式执行过程:

    // 1. 获取用户填写的用户名和密码
    final String name = et_username.getText().toString().trim();
    final String pwd = et_password.getText().toString().trim();
    // 2. 登录的逻辑
    new Thread() {
        public void run() {
            try {
                String path = "http://192.168.1.102/web/servlet/LoginServlet";
    
                // (1) 初始化HttpClient对象
                HttpClient client = new DefaultHttpClient();
                // (2) 创建一个post请求
                HttpPost post = new HttpPost(path);
    
                // ☆☆☆ 和get请求不同之处:封装我们请求的实体数据
                List<NameValuePair> parameters = new ArrayList<NameValuePair>();
                NameValuePair nameValuePair = new BasicNameValuePair(
                        "username", name);
                NameValuePair pwdValuePair = new BasicNameValuePair(
                        "password", pwd);
                parameters.add(nameValuePair);
                parameters.add(pwdValuePair);
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(
                        parameters);
                // (3) 封装请求数据到实体对象中
                post.setEntity(entity);
    
                // (4) 执行一个post请求
                HttpResponse response = client.execute(post);
                // (5) 返回请求状态码
                int code = response.getStatusLine().getStatusCode();
    
                if (code == 200) {
                    // 6. 获取服务器给我们返回的数据
                    InputStream in = response.getEntity().getContent();
                    // 7. 处理结果
                    final String content = StreamUtils.readStream(in);
                    // 8. 更新界面
                    showToast(content);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        };
    }.start();
    
  3. 两种提交方式不同之处:

    1. 路径不同
    
    2. get把提交的数据放在URL上提交到服务器,
       post把数据封装在NameValuePair对象中,然后提交到服务器
    
  4. 与HttpURLConnection方式获取服务器数据不同之处:

    易用性和灵活性更强
    

三、 第三种向服务器获取数据方式:Aynchttpclient

  1. Aynchttpclient介绍:

    Aynchttpclient是一个第三方的开源项目,可以在Github网站上获取源码,它封装了向服务器获取数据的方法,底层原理使用HttpClient实现
    
  2. 使用方法:

    1. 导入Aynchttpclient源码到工程中
    
    2. get方式:
            // (1) 初始化AsyncHttpClient对象
            AsyncHttpClient client = new AsyncHttpClient();
            // (2) 执行get请求
            client.get(path, new AsyncHttpResponseHandler() {};
    
    3. post方式:
            // (1)初始化AsyncHttpClient对象
            AsyncHttpClient client = new AsyncHttpClient();
            // (2) 封装参数数据
            RequestParams params = new RequestParams();
            params.put("username", name);
            params.put("password", pwd);
            // (3) 执行get请求
            client.post(path, new AsyncHttpResponseHandler() {}
    
  3. 使用Aynchttpclient上传文件

四、 Java实现多线程下载

  1. 多线程下载实现原理:

    原理:使用多线程下载相当于让更多的线程去竞争CPU资源,相对单线程下载服务器将分配给你更多的CPU资源,从而实现加速下载
    

  1. 实现过程:

    1. 使用HttpURLConnection获取服务器要下载文件的大小
    
        // 1. 创建一个url对象 参数就是网址
        URL url = new URL(path);
        // 2. 获取HttpURLConnection 链接对象
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        // 3. 设置参数 发送get请求
        conn.setRequestMethod("GET"); // 必须大写
        // 4. 设置链接网络的超时时间
        conn.setConnectTimeout(5000);
        // 5. 获取服务器返回的状态码
        int code = conn.getResponseCode();
        if (code == 200) {
            // 6. 获取文件的大小
            int length = conn.getContentLength();
    
    2. 在客户端创建一个与服务器端大小一样的空白文件
    
        RandomAccessFile raf = new RandomAccessFile("temp.exe", "rw");
        raf.setLength(length);
    
    3. 计算每个子线程下载的数据块大小和下载起始位置、结束位置
    
            // 二、☆☆☆ 算出每个线程下载的大小
            int threadSize = length / threadCount;
    
            // 三、☆☆☆ 计算每个线程下载的开始位置和结束位置
            for (int i = 0; i < threadCount; i++) {
                int startIndex = i * threadSize;
                int endIndex = (i + 1) * threadSize - 1;
                if (i == threadCount - 1) {
                    // 最后一个线程
                    endIndex = length - 1;
                }
            }
    
    4. 创建子线程开始下载数据
    
        // 三、☆☆☆ 开启多个线程,去真正的下载文件
        DownloadThread thread = new DownloadThread(path, startIndex, endIndex, i);
        thread.start();
    

五、 Java实现断点续传下载

实现过程:

  1. 实时记录线程下载的位置,并保存到文件中

        // 计算当前线程下载的位置并保存到文件中
        total += len;
        int currentThreadPosition = total + startIndex;
        RandomAccessFile ras = new RandomAccessFile(threadId
                + ".txt", "rwd");
        ras.write(String.valueOf(currentThreadPosition)
                .getBytes());
        ras.close();
    
  2. 读取记录上一次下载的位置的文件,继续下载

    File file = new File(threadId + ".txt");
    // 判断是否有上次下载未完成的文件,若有则继续下载
    if (file.exists() && file.length() > 0) {
    // 读取文件中存储的上次下载到的流的位置
    FileInputStream fis = new FileInputStream(file);
    BufferedReader br = new BufferedReader(
            new InputStreamReader(fis));
    String lastPosition = br.readLine();
    // 第二次下载的时候,按照这个位置继续下载
    // ☆☆☆ 告诉服务器,每个线程下载的开始位置和结束位置
    conn.setRequestProperty("Range", "bytes=" + lastPosition
            + "-" + endIndex);
    startIndex = Integer.parseInt(lastPosition);
    fis.close();
    

六、 使用开源项目XUtils实现多线程下载

  1. XUtils简介:

    开源的一个框架,包含了很多实用的Android工具,主要有四大模块功能:
    
        - DbUtils模块
        - ViewUtils模块
        - HttpUtils模块
        - BitmapUtils模块
    
    其中,HttpUtils模块提供了文件多线程断点续传下载功能
    
  2. 使用方法:

    1. 导入XUtils jar包或者在src目录下导入XUtils源码
    
    2. 创建HttpUtils实例对象:
            HttpUtils http = new HttpUtils();
    
    3. 调用HttpUtils对象的download方法:
            download(String url, String target, boolean autoResume, RequestCallBack<File> callback)
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值