由于智哥毕设的需要,我研究了一下AsyncHttpClient的使用,为其做了个小demo,在此记录一下demo编写过程,这也是我的第一篇博客,所以还是有些小激动啊。 废话不多说,开始正题。
我做的这个demo大致的演示效果是这样的。
1、环境搭建:起一个android模拟器和一个tomcat的服务器
2、下载演示:运行android端,当进入到初始界面时,后台会从服务器中下载一张图片到模拟器中并保存。
3、上传演示:android端将刚刚下载的图片又上传到服务器中
下面详细说说以上三步过程的实现。
一、环境搭建
android端我采用的是genymotion模拟器,SDK用的是Android6.0(API 23)。服务器端使用Tomcat 8.0.23,值得注意的是:需要在tomcat的配置文件context.xml中的<Context>标签中加入allowCasualMultipartParsing="true"属性,这是上传的需要,原因详见上传演示,修改后的标签为<Context allowCasualMultipartParsing="true">保存好后就可以将服务器运行起来了。环境搭建好,创建android端demo工程名为Hello_Android,服务器端demo工程名为Hello_Android_Server。
二、下载演示
在android端工程导入使用AsyncHttpClient所需的包,因为我使用的是1.4.9版本的jar包,所以还需要一个httpClient的jar包来协助,具体哪个地方使用这个jar包下面代码中会提到。(使用Maven的朋友请自行配置两个jar包依赖即可)无论你是直接使用jar包或是使用maven,都可以在http://mvnrepository.com/中直接查询到jar包的pom依赖或下载链接。
我们将靶文件拷贝至Hello_Android_Server的Web目录下,这样项目部署后,靶文件将在 [tomcat install directory]/webapps/Hello_Android_Server目录下找到。有了靶文件,我们就来看看如何在android端下载到靶文件。
看关键代码
android端
//创建AsyncHttpClient对象
AsyncHttpClient client = new AsyncHttpClient();
//利用AsyncHttpClient对象发起一个get请求来下载文件,
//FileAsyncHttpResponseHandler为充当接收http响应体的角色
client.get("http://192.168.56.1:8080/Hello_Android_Server/file.png",
new FileAsyncHttpResponseHandler(this) {
//当下载正确完成,回调onSuccess方法,
//该方法接收三个参数分别为:http状态码,http头信息数组,下载文件的临时副本
@Override
public void onSuccess(int statusCode, Header[] headers, File response) {
try {//此try-catch块中的代码将下载到的文件保存在一个目录下
// Context.getFilesDir(),该方法返回/data/data/[youPackageName]/files的File对象
FileOutputStream fileOutputStream = new FileOutputStream(
MainActivity.this.getFilesDir().getPath() + "/file.png");
FileInputStream fileInputStream = new FileInputStream(response);
byte[] bytes = new byte[(int) response.length()];
fileInputStream.read(bytes);
fileOutputStream.write(bytes);
fileOutputStream.flush();
fileInputStream.close();
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
/*********do something ...... ********/
/***************上传部分***************/
/*********do something ...... ********/
}
//下载失败时回调onFailure方法
@Override
public void onFailure(int statusCode, Header[] headers, Throwable throwable, File file) {
Log.i("file", "failure" + statusCode);
}
});
服务器端
//无
如果成功那么,可以打开android调试工具File Explorer来查看效果,我们可以从代码注释中写的保存路径下找到我们下载到的文件,如下图。
ok ! 下载功能 KO !
三、上传演示
在下载演示中有如下一段注释,这里就是我们写上传代码的部分。由于在这段注释之前的代码已经完成了下载工作,并且我们可以在app对应包下file目录中找到我们下载到的文件,那么下面我们就来看看如何将该文件再上传回服务器。
/*********do something ...... ********/
/***************上传部分***************/
/*********do something ...... ********/
android端代码:
/*上传部分*/
//找到上传的靶文件(此时的靶文件应该是我们刚刚下载到的文件)
File file = new File(MainActivity.this.getFilesDir().getPath(), "file.png");
//封装待发送参数(以键值对形式),即靶文件,内容类型设置为multipart/form-data
RequestParams params = new RequestParams();
try {
params.put("file", file, "multipart/form-data");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//没错,又是它
AsyncHttpClient uploader = new AsyncHttpClient();
//这次是post请求,看清楚,多了第二个参数params,其实也就是被封装的靶文件啦
//这次使用的响应体接收者是AsyncHttpResponseHandler,回调处理也简单,就是现实上传成功与否
uploader.post("http://192.168.56.1:8080/Hello_Android_Server/CatchHttpServlet", params,
new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
Log.i("upload", "upload success");
}
@Override
public void onFailure(int arg0, Header[] arg1, byte[] arg2, Throwable arg3) {
Log.i("upload", "upload failure");
}
});
服务器端代码:
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().append("Served at: ").append(request.getContextPath());
request.setCharacterEncoding("UTF-8");
//获取上传文件Part对象
Part file = request.getPart("file");
/*保存文件*/
InputStream inputStream = file.getInputStream();
byte[] bytes = new byte[(int) file.getSize()];
inputStream.read(bytes);
inputStream.close();
File newFile = new File(getServletContext().getRealPath("/uploadField/file.png"));
FileOutputStream fileOutputStream = new FileOutputStream(newFile);
fileOutputStream.write(bytes);
fileOutputStream.flush();
fileOutputStream.close();
System.out.println(file.getSize()+" "+getServletContext().getRealPath("/uploadField/file.png"));
}
是的服务器端代码就这么简单,但是因为是以Part对象的形式来接收靶文件,因此需要配置tomcat允许接收该种类型的参数,所以需要按照第一步中提到的方案修改context.xml中的<Context>标签。context.xml在如下图的位置中。
接下来,还需要为我们上传的文件设置一个目录,在服务器端项目Hello_Android_Server的Web目录下新建一个名为uploadField的文件夹,作为上传文件的保存目录。重新部署项目到tomcat,可以在[tomcat install directory]/ webapps / Hello_Android_Server/uploadField下查看我们上传的文件。
以上工作完成后,再次运行android端app,同时打开log cat和上面提到的uploadFiled目录。如果顺利,你将看到如下结果
。
ok 上传 KO !
本文只是介绍上传下载的基本的实现方案,就没有详细介绍AsyncHttpClient,网上介绍AsyncHttpClient的文章很多,不过要想学得牢靠些,最好还是去看官方的文档 http://loopj.com/android-async-http/ 。真的是一个不错的Http请求工具。另外demo代码十分简陋,为了快速实现功能而已,望见谅。
第一次写博客,欢迎指正,2016.04.25。