Android 网络通信方式
2015-11-07 16:15
495 查看
**
恍惚间,从事Android开发已经有半年有余了!之前一直在沉浸于项目中的Bug解决,颇有种一叶障目不见泰山的感觉,对Android网络通信这块儿缺乏一种宏观的认识,适逢一个难得的阴雨周末,躺着也是无聊,倒不如写写耍耍来的痛快!
Android端的开发,除了那些没有植入广告的单机版小游戏小应用,几乎大部分都要牵涉到网络数据的请求。当前Android端的网络编程可以分为两种:一种是通过Socket方式,另外一种则是基于http协议。这两种访问方式大不相同,Socket方式是面向TCP/UDP 协议的,而HTTP通信则是借助于Http协议,这两者分别建立在ISO 七层模型的传输层协议和应用层协议之上。(关于Android中的Socket和http区别,可以查看我的另外一篇文章—–《Android之Http,Socket和Tcp/Ip》)。
Socket通信在Android中应用不多,在桌面程序中倒是应用广泛如众所周知的QQ,关于Socket这篇文章不准备展开,主旨在于总结归纳一下Android 的HTTP通信方式。
1.2 HttpURLConnection和HttpClient的区别和联系
HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能:
1.2.1 HttpURLConnection。
HttpURLConnection是java的标准类,HttpURLConnection继承自URLConnection,可用于向指定网站发送GET请求、POST请求。它在URLConnection的基础上提供了如下便捷的方法:
在一般情况下,如果只是需要Web站点的某个简单页面提交请求并获取服务器响应,HttpURLConnection完全可以胜任。但在绝大部分情况下,Web站点的网页可能没这么简单,这些页面并不是通过一个简单的URL就可访问的,可能需要用户登录而且具有相应的权限才可访问该页面。在这种情况下,就需要涉及Session、Cookie的处理了,如果打算使用HttpURLConnection来处理这些细节,当然也是可能实现的,只是处理起来难度就大了。
1.2.2 关于HttpClient
为了更好地处理向Web站点请求,包括处理Session、Cookie等细节问题,Apache开源组织提供了一个HttpClient项目,看它的名称就知道,它是一个简单的HTTP客户端(并不是浏览器),可以用于发送HTTP请求,接收HTTP响应。但不会缓存服务器的响应,不能执行HTML页面中嵌入的Javascript代码;也不会对页面内容进行任何解析、处理。
简单来说,HttpClient就是一个增强版的HttpURLConnection,HttpURLConnection可以做的事情HttpClient全部可以做;HttpURLConnection没有提供的有些功能,HttpClient也提供了,但它只是关注于如何发送请求、接收响应,以及管理HTTP连接。
使用HttpClient发送请求、接收响应很简单,只要如下几步即可。
创建HttpClient对象。
如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
调用HttpClient对象的execute(HttpUriRequest request)发送请求,执行该方法返回一个HttpResponse。
调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
另外,Android已经成功地集成了HttpClient,这意味着开发人员可以直接在Android应用中使用Httpclient来访问提交请求、接收响应。
比如一个Android应用需要向指定页面发送请求,但该页面并不是一个简单的页面,只有当用户已经登录,而且登录用户的用户名有效时才可访问该页面。如果使用HttpURLConnection来访问这个被保护的页面,那么需要处理的细节就太复杂了。
其实访问Web应用中被保护的页面,使用浏览器则十分简单,用户通过系统提供的登录页面登录系统,浏览器会负责维护与服务器之间的Sesion,如果用户登录的用户名、密码符合要求,就可以访问被保护资源了。
在Android应用程序中,则可使用HttpClient来登录系统,只要应用程序使用同一个HttpClient发送请求,HttpClient会自动维护与服务器之间的Session状态,也就是说程序第一次使用HttpClient登录系统后,接下来使用HttpClient即可访问被保护页了。
详情可点击链接:
http://blog.csdn.net/wszxl492719760/article/details/8522714
**
2.1 HttpClient使用
使用背景:Android 客户端访问Java后台,获取后台数据,数据请求和下载都采用UTF-8编码。
2.1.1 关于handleEntity
网络数据的处理说到底也是对java字节流的处理,handleEntity就是对java后台返回的字节流进行处理后封装为字符对象。
代码如下:
2.2 HttpURLConnection 使用
2.2.1 获取输入流
2.2.2 获取InputStream后转化为Bitmap
2.2.3 将 Input对象写入文件
**
网上查阅一番资料后再对照下自己的代码,恍然间好困!看代码真的好累啊…呵呵,其实网络操作说白了就是java的网络核心篇加上java的字节流操作,其中需要注意的地方先列出来以备后用:
1.HTTP协议之post和get的区别。
2.在Android 4.0之后,不允许在主线程中进行网络连接,必须采用线程机制。
3.建议采用线程 –Hander –Message 的Android消息机制进行网络数据操作。
好了,越扯越多了,说到Android的消息机制我现在还是有点昏,就先总结到这里吧!
前言:
**恍惚间,从事Android开发已经有半年有余了!之前一直在沉浸于项目中的Bug解决,颇有种一叶障目不见泰山的感觉,对Android网络通信这块儿缺乏一种宏观的认识,适逢一个难得的阴雨周末,躺着也是无聊,倒不如写写耍耍来的痛快!
Android端的开发,除了那些没有植入广告的单机版小游戏小应用,几乎大部分都要牵涉到网络数据的请求。当前Android端的网络编程可以分为两种:一种是通过Socket方式,另外一种则是基于http协议。这两种访问方式大不相同,Socket方式是面向TCP/UDP 协议的,而HTTP通信则是借助于Http协议,这两者分别建立在ISO 七层模型的传输层协议和应用层协议之上。(关于Android中的Socket和http区别,可以查看我的另外一篇文章—–《Android之Http,Socket和Tcp/Ip》)。
Socket通信在Android中应用不多,在桌面程序中倒是应用广泛如众所周知的QQ,关于Socket这篇文章不准备展开,主旨在于总结归纳一下Android 的HTTP通信方式。
一.HTTP通信详细归纳
1.1 http网络连接实现方式可以细分为两类实现:1.借助于Java核心包 java.net中的HttpURLConnection 类 2.借助于Apache开源组织提供的HttpClient类。 org.apache.http.client.HttpClient;
1.2 HttpURLConnection和HttpClient的区别和联系
HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能:
1.2.1 HttpURLConnection。
HttpURLConnection是java的标准类,HttpURLConnection继承自URLConnection,可用于向指定网站发送GET请求、POST请求。它在URLConnection的基础上提供了如下便捷的方法:
int getResponseCode():获取服务器的响应代码。 String getResponseMessage():获取服务器的响应消息。 String getResponseMethod():获取发送请求的方法。 void setRequestMethod(String method):设置发送请求的方法。
在一般情况下,如果只是需要Web站点的某个简单页面提交请求并获取服务器响应,HttpURLConnection完全可以胜任。但在绝大部分情况下,Web站点的网页可能没这么简单,这些页面并不是通过一个简单的URL就可访问的,可能需要用户登录而且具有相应的权限才可访问该页面。在这种情况下,就需要涉及Session、Cookie的处理了,如果打算使用HttpURLConnection来处理这些细节,当然也是可能实现的,只是处理起来难度就大了。
1.2.2 关于HttpClient
为了更好地处理向Web站点请求,包括处理Session、Cookie等细节问题,Apache开源组织提供了一个HttpClient项目,看它的名称就知道,它是一个简单的HTTP客户端(并不是浏览器),可以用于发送HTTP请求,接收HTTP响应。但不会缓存服务器的响应,不能执行HTML页面中嵌入的Javascript代码;也不会对页面内容进行任何解析、处理。
简单来说,HttpClient就是一个增强版的HttpURLConnection,HttpURLConnection可以做的事情HttpClient全部可以做;HttpURLConnection没有提供的有些功能,HttpClient也提供了,但它只是关注于如何发送请求、接收响应,以及管理HTTP连接。
使用HttpClient发送请求、接收响应很简单,只要如下几步即可。
创建HttpClient对象。
如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
调用HttpClient对象的execute(HttpUriRequest request)发送请求,执行该方法返回一个HttpResponse。
调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
另外,Android已经成功地集成了HttpClient,这意味着开发人员可以直接在Android应用中使用Httpclient来访问提交请求、接收响应。
比如一个Android应用需要向指定页面发送请求,但该页面并不是一个简单的页面,只有当用户已经登录,而且登录用户的用户名有效时才可访问该页面。如果使用HttpURLConnection来访问这个被保护的页面,那么需要处理的细节就太复杂了。
其实访问Web应用中被保护的页面,使用浏览器则十分简单,用户通过系统提供的登录页面登录系统,浏览器会负责维护与服务器之间的Sesion,如果用户登录的用户名、密码符合要求,就可以访问被保护资源了。
在Android应用程序中,则可使用HttpClient来登录系统,只要应用程序使用同一个HttpClient发送请求,HttpClient会自动维护与服务器之间的Session状态,也就是说程序第一次使用HttpClient登录系统后,接下来使用HttpClient即可访问被保护页了。
详情可点击链接:
http://blog.csdn.net/wszxl492719760/article/details/8522714
**
二.在代码中的实际使用
**2.1 HttpClient使用
使用背景:Android 客户端访问Java后台,获取后台数据,数据请求和下载都采用UTF-8编码。
/** * 请求服务器的方法 * @param Url * @param jso * @return */ public String NetWork(String servletName,List<String> Name,List<String> Value){ //创建默认的 HttpClient 实例 HttpClient httpClient = new DefaultHttpClient(); // 采用http "Post"访问Java后台 HttpPost httpPost = new HttpPost(url+servletName); //post方式需要传入的参数 HttpParams hp = httpPost.getParams(); hp.setIntParameter(HttpConnectionParams.SO_TIMEOUT, 30000); // 超时设置 hp.setIntParameter(HttpConnectionParams.CONNECTION_TIMEOUT, 30000);// 连接超时 try { if(Name!=null){ // 来自org.apache.http包。用于保存键值对name-value List<NameValuePair> formParams = new ArrayList<NameValuePair>(); for (int i = 0; i < Name.size(); i++) { formParams.add(new BasicNameValuePair(Name.get(i), Value.get(i))); } //网络访问传入的参数统一采用UTF-8编码 UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(formParams, "UTF-8"); httpPost.setEntity(urlEncodedFormEntity); } // java后台返回的response对象 HttpResponse httpResponse = null; httpResponse = httpClient.execute(httpPost); //respons对象携带的内容 HttpEntity httpEntity = httpResponse.getEntity(); if (httpEntity != null) { //java 后台返回内容采用UTF-8编码 String content = handleEntity(httpEntity, "UTF-8"); return content; } else { return null; } } catch (Exception e) { e.printStackTrace(); return null; }finally { //关闭连接,释放资源 httpClient.getConnectionManager().shutdown(); } }
2.1.1 关于handleEntity
网络数据的处理说到底也是对java字节流的处理,handleEntity就是对java后台返回的字节流进行处理后封装为字符对象。
代码如下:
public String handleEntity(HttpEntity entity, String charset) throws IOException { if (entity == null) return null; //网络数据使用字节流对象存储 ByteArrayOutputStream outStream = new ByteArrayOutputStream(); //字节buffer byte[] buffer = new byte[1024]; @SuppressWarnings("unused") int len = -1; //获取输入字节流对象 InputStream is = entity.getContent(); while ((len = is.read(buffer)) != -1) { //将buffer数据写入字节流对象outStream outStream.write(buffer, 0, len); } byte[] data = outStream.toByteArray(); outStream.close(); is.close(); // 生成指定编码格式的字符 return new String(data, charset); }
2.2 HttpURLConnection 使用
2.2.1 获取输入流
// //由于得到一个InputStream对象 public InputStream getInputStream(String urlStr) throws IOException { InputStream is = null; try { url = new URL(urlStr); HttpURLConnection urlConn = (HttpURLConnection)url.openConnection(); urlConn.setRequestMethod("GET"); urlConn.setDoInput(true); urlConn.setDoOutput(true); urlConn.setUseCaches(false); urlConn.setConnectTimeout(5000); urlConn.setReadTimeout(5000); ////实现连接 urlConn.connect(); if (urlConn.getResponseCode() == 200) { is = urlConn.getInputStream() ; //} } catch(MalformedURLException e) { e.printStackTrace(); } return is; }
2.2.2 获取InputStream后转化为Bitmap
图片操作
//网络图片获取 //urlpath = "http://*****/splashy_above.png" public static Bitmap getImage(String urlpath) throws Exception { URL url = new URL(urlpath); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5*1000); conn.setRequestMethod("GET"); Bitmap bitmap = null; if(conn.getResponseCode() == 200) { InputStream inputStream = conn.getInputStream(); bitmap = BitmapFactory.decodeStream(inputStream); } return bitmap; }
2.2.3 将 Input对象写入文件
文件操作。
*将一个InputStream里面的数据写入到SD卡中 * */ public File write2SDFromInput(String path,String fileName,InputStream input) { File file = null; OutputStream output = null; try { //将一个InputStream 对象的数据写入到 BufferedOutputStream bos对象中 byte[] arr = new byte[1]; //缓冲流和字节流对象对接 ByteArrayOutputStream baos = new ByteArrayOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(baos); //循环操作将输入流inputStream对象中的字节流写入到字节缓存输出流中 int n = input.read(arr); while (n > 0) { bos.write(arr); n = input.read(arr); } bos.close(); //该函数只是在SD卡上创建文件夹 createSDDir(path); //在上面创建好文件夹下创建文件 file = createSDFile(path + fileName); output = new FileOutputStream(file); output.write(baos.toByteArray()); output.flush(); baos.close(); } catch(Exception e) { e.printStackTrace(); } finally { try { output.close(); } catch(Exception e) { e.printStackTrace(); } } return file; }
**
三.总结
**网上查阅一番资料后再对照下自己的代码,恍然间好困!看代码真的好累啊…呵呵,其实网络操作说白了就是java的网络核心篇加上java的字节流操作,其中需要注意的地方先列出来以备后用:
1.HTTP协议之post和get的区别。
2.在Android 4.0之后,不允许在主线程中进行网络连接,必须采用线程机制。
3.建议采用线程 –Hander –Message 的Android消息机制进行网络数据操作。
Thread t.start(); t.run()里面进行网络访问。 t.run()之后访问完成后发送Message。 Handler 截获message后将接收到的数据在View中予以展示。
好了,越扯越多了,说到Android的消息机制我现在还是有点昏,就先总结到这里吧!
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories