热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android基础4(get、post乱码解决、Asynchttpclient的GET_POST访问网络、上传文件、多线程下载、多线程下载的Android移植、XUtils实现多线程下载)

1.post方式提交数据的中文乱码解决(重点)解决中文乱码的方法:保证客户端和服务器端使用的字符集编码一致。Android应用程序默认使用的字符集是UTF-8;Tomcat默认的字符集编

 

1.post方式提交数据的中文乱码解决(重点)

解决中文乱码的方法:

 保证客户端和服务器端使用的字符集编码一致。

 Android应用程序默认使用的字符集是UTF-8;

  //Tomcat默认的字符集编码是iso-8859-1,默认是iso-8859-1进行转码  

 String username = request.getParameter("username");   

String password = request.getParameter("password");             

String  newUsername = new String(username.getBytes("iso-8859-1"),"UTF-8");   

String  newPassword = new String(password.getBytes("iso-8859-1"),"UTF-8");   

System.out.println(newUsername);   

System.out.println(newPassword);   

  if("中国".equals(newUsername) && "发展".equals(newPassword)){  

 //Tomcat默认的字符集编码是iso-8859-1,默认是iso-8859-1进行转码,当它发现使用iso-8859-1不能编码中文的时候,   //会使用操作系统使用的本地码表(字符集编码)进行编码   

 response.getOutputStream().write("登陆成功".getBytes("UTF-8"));  

 }else

{    response.getOutputStream().write("登陆失败".getBytes("UTF-8"));  

}

2.get提交数据乱码的解决:

 保证客户端和服务器端使用的字符集编码一致.  Android应用程序默认使用的字符集是UTF-8.  

3.使用HttpClient向服务器端提交数据

  HttpClient是apache下的子项目,轻量级的浏览器。

 使用步骤:  

1、创建一个浏览器:  

2、输入网址:  

3、按回车,执行请求:

* 使用GET方式提交数据:

  代码:

  //1、创建一个浏览器:    

HttpClient client = new DefaultHttpClient();

  //2、输入网址:    

HttpGet http = new HttpGet(path);

  //3、按回车,执行请求:   

 //服务器返回的所有数据都封装到了response里   

 HttpResponse respOnse= client.execute(http);    

//得到响应码(状态码)    

int code = response.getStatusLine().getStatusCode();    

if (200 == code) {    

// 获得服务器端的响应数据    

InputStream is = response.getEntity().getContent();       

String result = StreamTools.readStream(is);    

Message msg = Message.obtain();    

msg.obj = result;    

handler.sendMessage(msg);   

}         

* 使用POST方式发送提交数据:        

代码:   

package com.qaa.qqlogin;     

import java.io.InputStream;   

import java.net.URLEncoder;   

import java.util.ArrayList;   

import java.util.List;      

import org.apache.http.HttpResponse;   

import org.apache.http.client.HttpClient;   

import org.apache.http.client.entity.UrlEncodedFormEntity;   

import org.apache.http.client.methods.HttpPost;   

import org.apache.http.impl.client.DefaultHttpClient;   

import org.apache.http.message.BasicNameValuePair;      

import android.app.Activity;   

import android.os.Bundle;   

import android.os.Handler;   

import android.os.Message;   

import android.text.TextUtils;   

import android.view.View;   

import android.widget.EditText;   

import android.widget.Toast;      

public class MainActivity extends Activity {    

 private EditText et_qq;   

private EditText et_pwd;      

private Handler handler = new Handler(){        

public void handleMessage(Message msg) {     

String result = (String) msg.obj;          

Toast.makeText(MainActivity.this, result, 0).show();   

 };   

};     

 @Override   

protected void onCreate(Bundle savedInstanceState) {    

super.onCreate(savedInstanceState);    

setContentView(R.layout.activity_main);        

et_qq = (EditText) findViewById(R.id.et_qq);    

et_pwd = (EditText) findViewById(R.id.et_pwd);   

}       

 public void login(View view){    

final String qq = et_qq.getText().toString().trim();    

final String pwd = et_pwd.getText().toString().trim();        

if(TextUtils.isEmpty(qq) || TextUtils.isEmpty(pwd)){     

Toast.makeText(this, "qq号码或者密码不能为空", 0).show();     

return;    

}else

{     

final String path = "http://192.168.20.91:8080/web/servlet/LoginServlet";     

new Thread() {      

public void run() {       

try {        

String data = "username="+URLEncoder.encode(qq,"UTF-8")+"&password="+URLEncoder.encode(pwd,"UTF-8");                        

//      1、创建一个浏览器:       

 HttpClient client = new DefaultHttpClient();   

//      2、输入网址:        

HttpPost http = new HttpPost(path);      

  //封装提交的参数        

BasicNameValuePair value1 = new BasicNameValuePair("username",qq) ;       

 BasicNameValuePair value2 = new BasicNameValuePair("password",pwd) ;                

List parameters = new ArrayList();        

parameters.add(value1);       

 parameters.add(value2);        

//把提交的数据封装到form实体对象中        

//默认是iso-8859-1进行url编码,需要显示的指定字符集编码        

UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters,"UTF-8");               

 //设置提交的数据实体        

http.setEntity(entity);   

//      3、按回车,执行请求:        

HttpResponse respOnse= client.execute(http);               

 //得到响应码        

int code = response.getStatusLine().getStatusCode();       

 if (200 == code) {        

 // 获得服务器端的响应数据        

 InputStream is = response.getEntity().getContent();         

String result = StreamTools.readStream(is);                  

Message msg = Message.obtain();         

msg.obj = result;         

handler.sendMessage(msg);        

}       

} catch (Exception e) {        

e.printStackTrace();       

}     

 };    

 }.start();    

}  

 }

 }

5.使用开源项目Asynchttpclient的GET_POST访问网络

* 使用GET方式提交数据:

代码:

 package com.qaa.qqlogin;

 import java.io.InputStream;  

import java.net.HttpURLConnection;  

import java.net.URL;  

import java.net.URLEncoder;    

import org.apache.http.Header;    

import com.loopj.android.http.AsyncHttpClient;  

import com.loopj.android.http.AsyncHttpResponseHandler;    

import android.app.Activity;  

import android.os.Bundle;  

import android.os.Handler;  

import android.os.Message;  

import android.text.TextUtils;  

import android.view.View;  

import android.widget.EditText;  

import android.widget.Toast;    

public class MainActivity extends Activity {     

private EditText et_qq;   

private EditText et_pwd;     

@Override   

protected void onCreate(Bundle savedInstanceState)

{    

super.onCreate(savedInstanceState);    

setContentView(R.layout.activity_main);      

et_qq = (EditText) findViewById(R.id.et_qq);    

et_pwd = (EditText) findViewById(R.id.et_pwd);   

}     

public void login(View view)

{    

final String qq = et_qq.getText().toString().trim();    

final String pwd = et_pwd.getText().toString().trim();      

if (TextUtils.isEmpty(qq) || TextUtils.isEmpty(pwd))

{     

Toast.makeText(this, "qq号码或者密码不能为空", 0).show();     

return;    }

else

{          

String path = "http://192.168.20.91:8080/web/servlet/LoginServlet?username="       + qq + "&password="+pwd;         

 //1、创建一个浏览器对象     

AsyncHttpClient client = new AsyncHttpClient();     

//2、发送一个GET请求     

client.get(path, new AsyncHttpResponseHandler() {           

 /** * 请求处理成功后调用这个方法     

* statusCode 响应码 200 404 503      

* headers 响应头信息      

* responseBody 服务器返回的响应数据(如:登陆成功、失败等) */      

@Override      

public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {       

Toast.makeText(MainActivity.this, new String(responseBody), 0).show();      }

     /**      

* 请求处理失败后调用这个方法      

* statusCode 响应码 200 404 503      

* headers 响应头信息      

* responseBody 服务器返回的响应数据(如:登陆成功、失败等)      

* Throwable 异常对象       */      

@Override      

public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {

        error.printStackTrace();              

Toast.makeText(MainActivity.this, "请求处理失败", 0).show();      

}     

});    

}   

}    

}

* 使用POST方式提交数据:

代码:

 package com.qaa.qqlogin;

 import java.io.InputStream;  

import java.net.HttpURLConnection;  

import java.net.URL;  

import java.net.URLEncoder;    

import org.apache.http.Header;    

import com.loopj.android.http.AsyncHttpClient;  

import com.loopj.android.http.AsyncHttpResponseHandler;  

import com.loopj.android.http.RequestParams;    

import android.app.Activity;  

import android.os.Bundle;  

import android.os.Handler;  

import android.os.Message;  

import android.text.TextUtils;  

import android.view.View;  

import android.widget.EditText;  

import android.widget.Toast;    

public class MainActivity extends Activity

{     

private EditText et_qq;   

private EditText et_pwd;     

@Override   

protected void onCreate(Bundle savedInstanceState)

{    

super.onCreate(savedInstanceState);    

setContentView(R.layout.activity_main);        

et_qq = (EditText) findViewById(R.id.et_qq);    

et_pwd = (EditText) findViewById(R.id.et_pwd);   

}

  public void login(View view)

{    

final String qq = et_qq.getText().toString().trim();    

final String pwd = et_pwd.getText().toString().trim();        

if(TextUtils.isEmpty(qq) || TextUtils.isEmpty(pwd)){     

Toast.makeText(this, "qq号码或者密码不能为空", 0).show();     

return;    

}else

{     

String path = "http://192.168.20.91:8080/web/servlet/LoginServlet";

 AsyncHttpClient client = new AsyncHttpClient();     

//封装要提交的数据     

RequestParams params = new RequestParams();     

params.put("username", qq);     

params.put("password", pwd);         

 //执行post请求     

//path 请求的url    

 //params 封装要提交的数据     

//responseHandler 响应的处理器     

client.post(path, params, new AsyncHttpResponseHandler()

{      

/**      

* 请求处理成功后调用这个方法      

* statusCode 响应码 200 404 503      

* headers 响应头信息      

* responseBody 服务器返回的响应数据(如:登陆成功、失败等)       */      

@Override      

public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {       

Toast.makeText(MainActivity.this, new String(responseBody), 0).show();      

}      

/**      

* 请求处理失败后调用这个方法      

* statusCode 响应码 200 404 503      

* headers 响应头信息      

* responseBody 服务器返回的响应数据(如:登陆成功、失败等)      

* Throwable 异常对象       */      

@Override      

public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {       

error.printStackTrace();       

Toast.makeText(MainActivity.this, "请求处理失败", 0).show();      

}     

});    

}   

}   

}

##6上传文件(重点)

代码:       

String path = "http://192.168.20.91:8080/web/servlet/UploadServlet";          

AsyncHttpClient client = new AsyncHttpClient();     

//封装要提交的数据     

RequestParams params = new RequestParams();          

//上传文件     

File file = new File(fildir);     

params.put("file", file);          

//执行post请求     

//path 请求的url     

//params 封装要提交的数据     

//responseHandler 响应的处理器     

client.post(path, params, new AsyncHttpResponseHandler() {      

/**      

* 请求处理成功后调用这个方法      

* statusCode 响应码 200 404 503      

* headers 响应头信息      

* responseBody 服务器返回的响应数据(如:登陆成功、失败等)       */      

@Override      

public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {       

Toast.makeText(MainActivity.this, new String(responseBody), 0).show();      

}      

/**      

* 请求处理失败后调用这个方法      

* statusCode 响应码 200 404 503      

* headers 响应头信息      

* responseBody 服务器返回的响应数据(如:登陆成功、失败等)      

* Throwable 异常对象       */      

@Override      

public void onFailure(int statusCode, Header[] headers,byte[] responseBody, Throwable error) {              

error.printStackTrace();       

Toast.makeText(MainActivity.this, "请求处理失败", 0).show();      

}     

});  

7.多线程下载的原理

多线程下载文件的步骤:

 1、在客户端本地创建一个与服务器端一样大小的空白文件:  

(1)创建空白文件:RandomAccessFile setlength();  

(2)获取空白文件大小:content-length;    

2、确定每个子线程下载数据块大小:     

blocksize=length/threadCount:10/3=3     

确定每个子线程下载数据的起始位置和结束位置:  

第0个线程:开始位置 0*3=0 结束位置:(0+1)*3-1  

第1个线程:开始位置 1*3=3 结束位置:(1+1)*3-1  ...  

第n个线程:开始位置 n*blocksize  结束位置:(n+1)*blocksize-1  n是线程的id  最后一个子线程下载的结束位置:length-1

 3、创建子线程,下载对应数据块:

 4、确定每个子线程什么下载完毕,标识整个文件都下载完成:使用变量来标识;    

 

##8.多线程下载的Android移植

代码:

MainActivity.java:

package com.qaa.multithreaddownloader;    

import java.io.RandomAccessFile;  

import java.net.HttpURLConnection;  

import java.net.URL;        

import android.app.Activity;  

import android.os.Bundle;  

import android.os.Environment;  

import android.text.TextUtils;  

import android.view.View;  

import android.widget.EditText;  

import android.widget.Toast;    

public class MainActivity extends Activity {

 private EditText et_path;

 private EditText et_threadCount;    

private static int threadCount = 3;

 @Override  

protected void onCreate(Bundle savedInstanceState)

{   super.onCreate(savedInstanceState);  

 setContentView(R.layout.activity_main);     

 et_path = (EditText) findViewById(R.id.et_path);  

 et_threadCount = (EditText) findViewById(R.id.et_threadCount);

 }  

 public void download(View view){      

final String path = et_path.getText().toString().trim();  

 String tcStr = et_threadCount.getText().toString().trim();   

if(TextUtils.isEmpty(path)){    

Toast.makeText(this, "请输入下载文件的网络路径", 0).show();    

return;   }

else{   

 if(!TextUtils.isEmpty(tcStr))

{     threadCount = Integer.parseInt(tcStr);   

 }    

new Thread(){     

public void run() {      

// 1、在客户端本地创建一个与服务器端一样大小的空白文件:     

 try {              

URL url = new URL(path);      

 HttpURLConnection cOnn= (HttpURLConnection) url.openConnection();      

 conn.setRequestMethod("GET");      

 conn.setConnectTimeout(3000);      

 int code = conn.getResponseCode();       

if (200 == code) {        

int length = conn.getContentLength();        

RandomAccessFile raf = new RandomAccessFile(Environment.getExternalStorageDirectory()+"/temp.exe", "rw");        

raf.setLength(length);        

// 2、确定每个子线程下载数据块大小:        

int blockSize = length / threadCount;        

for (int threadId = 0; threadId

// blocksize=length/threadCount:10/3=3         

// 确定每个子线程下载数据的起始位置和结束位置:        

 // 第0个线程:开始位置 0*3=0 结束位置:(0+1)*3-1        

 // 第1个线程:开始位置 1*3=3 结束位置:(1+1)*3-1         

// ...         // 第n个线程:开始位置 n*blocksize 结束位置:(n+1)*blocksize-1         // n是线程的id        

 // 最后一个子线程下载的结束位置:length-1        

 int startIndex = threadId * blockSize;        

 int endIndex = (threadId + 1) * blockSize - 1;       

  if (threadId == (threadCount - 1)) {         

 endIndex = length - 1;         }         

// 3、创建子线程,下载对应数据块:         

new ChildThreadDownLoader(threadId,startIndex,endIndex,path).start();       

 }      

 }    

  } catch (Exception e) {

      e.printStackTrace();    

  }

    };    

}.start();   

}   

 }

ChildThreadDownLoader.java:

 package com.qaa.multithreaddownloader;    

import java.io.IOException;  

import java.io.InputStream;  

import java.io.RandomAccessFile;  

import java.net.HttpURLConnection;  

import java.net.MalformedURLException;  

import java.net.ProtocolException;  

import java.net.URL;    

import android.os.Environment;    

public class ChildThreadDownLoader extends Thread{    

private int threadId;  

private int startIndex;  

private int endIndex;  

private String path;  

private  static int runningThreadCount = 3;    

public ChildThreadDownLoader(int threadId, int startIndex, int endIndex,    String path) {   

super();   

this.threadId = threadId;  

 this.startIndex = startIndex;   

this.endIndex = endIndex;   

this.path = path;  }    

@Override  

public void run() {   

try {    

URL url = new URL(path);    

HttpURLConnection cOnn= (HttpURLConnection) url.openConnection();    

conn.setRequestMethod("GET");    

conn.setConnectTimeout(3000);    

//告诉服务器子线程请求的数据范围    

conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);   

 //请求部分数据成功返回的响应码是206    

int code = conn.getResponseCode();    

if(206 == code){     

InputStream is = conn.getInputStream();     

RandomAccessFile raf = new RandomAccessFile(Environment.getExternalStorageDirectory()+"/temp.exe","rwd");     

raf.seek(startIndex);    System.out.println("线程"+threadId+"正在下载...................");     

byte[] buffer = new byte[1024*1024];     

int len = 0;     

while((len = is.read(buffer)) != -1){      

raf.write(buffer, 0, len);     

}     

is.close();    

 raf.close();        

 }        

System.out.println("线程"+threadId+"下载完毕...................");   

 // 4、确定每个子线程什么下载完毕,标识整个文件都下载完成:使用变量来标识;    

synchronized (ChildThreadDownLoader.class)

{     runningThreadCount --;    

 if(runningThreadCount == 0){      

System.out.println("文件下载完成..............");    

 }   

 }          

 }

catch (Exception e)

{    e.printStackTrace();  

 }  

}

 }

10.开源项目XUtils实现多线程下载(重点)

代码:

 package com.qaa.multithreaddownloader;

 import java.io.File;  

import java.io.RandomAccessFile;  

import java.net.HttpURLConnection;  

import java.net.URL;  

 import com.lidroid.xutils.HttpUtils;  

import com.lidroid.xutils.exception.HttpException;  

import com.lidroid.xutils.http.ResponseInfo;  

import com.lidroid.xutils.http.callback.RequestCallBack;        

import android.app.Activity;  

import android.os.Bundle;  

import android.os.Environment;  

import android.text.TextUtils;  

import android.view.View;  

import android.widget.EditText;  

import android.widget.Toast;    

public class MainActivity extends Activity {

 private EditText et_path;

 private EditText et_threadCount;    

private static int threadCount = 3;

 @Override  

protected void onCreate(Bundle savedInstanceState) {   

super.onCreate(savedInstanceState);   

setContentView(R.layout.activity_main);      

et_path = (EditText) findViewById(R.id.et_path);   

et_threadCount = (EditText) findViewById(R.id.et_threadCount);  

}    

public void download(View view){      

String path = et_path.getText().toString().trim();   

String tcStr = et_threadCount.getText().toString().trim();   

if(TextUtils.isEmpty(path))

{    

Toast.makeText(this, "请输入下载文件的网络路径", 0).show();    

return;   }

else{    

if(!TextUtils.isEmpty(tcStr))

{     threadCount = Integer.parseInt(tcStr);    

}        

HttpUtils http = new HttpUtils();    

http.download(path, Environment.getExternalStorageDirectory()+"/temp.exe",  new RequestCallBack()

{

          @Override          

public void onStart()

{              

Toast.makeText(MainActivity.this, "开始下载...", 0).show();          

}

          @Override          

public void onLoading(long total, long current, boolean isUploading)

{      System.out.println(current+"/"+total+"-------------------------------");                    

}

       

    @Override     

public void onFailure(HttpException arg0, String arg1) {      

Toast.makeText(MainActivity.this, "下载失败...", 0).show();     }

    @Override     

public void onSuccess(ResponseInfo arg0) {      Toast.makeText(MainActivity.this, "下载完成,文件保存在"+arg0.result.getPath(), 0).show();     

}  

 });  

 }   

 }

 }

 


推荐阅读
  • 本文详细解析了Java中流的概念,特别是OutputStream和InputStream的区别,并通过实际案例介绍了如何实现Java对象的序列化。文章不仅解释了流的基本概念,还探讨了序列化的重要性和具体实现步骤。 ... [详细]
  • 提升接口测试效率的关键:用例与工具的综合应用
    本文将探讨如何通过有效的接口测试用例设计和工具选择,显著提高接口测试的效率和质量。 ... [详细]
  • 解决JavaWeb项目中因IPv6导致的IP转换错误
    本文探讨了在JavaWeb项目中,当尝试将客户端IP地址从字符串形式转换为整数时遇到的问题,并提供了详细的解决方案。具体问题表现为在本地环境中通过`request.getRemoteHost()`获取到的IP地址为IPv6格式,而非预期的IPv4格式。 ... [详细]
  • 本文探讨了在使用Apache Flink向Kafka发送数据过程中遇到的事务频繁失败问题,并提供了详细的解决方案,包括必要的配置调整和最佳实践。 ... [详细]
  • Web网络基础
    目录儿1使用HTTP协议访问Web2HTTP的诞生2.1因特网的起源2.2互联网、因特网与万维网2.3万维网与HTTP3网络基础TCPIP3.1TCPIP协议族3.2TCPIP的分 ... [详细]
  • 微信小程序支付官方参数小程序中代码后端发起支付代码支付回调官方参数文档地址:https:developers.weixin.qq.comminiprogramdeva ... [详细]
  • 本文基于《Core Java Volume 2》的内容,深入探讨了网络编程中通过POST方法提交表单数据的技术细节,包括GET与POST方法的区别、POST提交的具体步骤及常见问题处理。 ... [详细]
  • C#爬虫Fiddler插件开发自动生成代码
    哈喽^_^一般我们在编写网页爬虫的时候经常会使用到Fiddler这个工具来分析http包,而且通常并不是分析一个包就够了的,所以为了把更多的时间放在分析http包上,自动化生成 ... [详细]
  • PHP网站部署指南:从零开始搭建PHP网站
    本文提供了详细的步骤指导,帮助开发者在不同环境下成功部署PHP网站,包括在IIS和Apache服务器上的具体操作。 ... [详细]
  • 本文详细介绍如何在Spring Boot项目中集成和使用JPA,涵盖JPA的基本概念、Spring Data JPA的功能以及具体的操作步骤,帮助开发者快速掌握这一强大的持久化技术。 ... [详细]
  • 本文探讨了在Node.js环境中如何有效地捕获标准输出(stdout)的内容,并将其存储到变量中。通过具体的示例和解决方案,帮助开发者解决常见的输出捕获问题。 ... [详细]
  • Flask中路由的基础定义与应用
    本文介绍了如何在Flask框架中通过装饰器为视图函数指定访问路径,并详细讲解了带参数路由及指定请求方法的实现方式。 ... [详细]
  • 本文探讨了Web API 2中特性的路由机制,特别是如何利用它来构建RESTful风格的URI。文章不仅介绍了基本的特性路由使用方法,还详细说明了如何通过特性路由进行API版本控制、HTTP方法的指定、路由前缀的应用以及路由约束的设置。 ... [详细]
  • 帝国cms各数据表有什么用
    CMS教程|帝国CMS帝国cmsCMS教程-帝国CMS精易编程助手源码,ubuntu桥接设置,500错误是tomcat吗,爬虫c原理,php会话包括什么,营销seo关键词优化一般多 ... [详细]
  • 探讨了生成时间敏感的一次性伪随机密码的方法,旨在通过加入时间因素防止重放攻击。 ... [详细]
author-avatar
平凡简单
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有