Android网络编程网上文章总结



关于网络编程,网上也有许多好的文章,这里我就选了几篇觉得不错的归纳到了一起,仅供参考


Android网络编程概述


首先,应该了解的几个问题:

1)Android平台网络相关API接口

 a) java.net.*(标准Java接口)

 java.net.*提供与联网有关的类,包括流、数据包套接字(socket)、Internet协议、常见Http处理等。比如:创建URL,以及URLConnection/HttpURLConnection对象、设置链接参数、链接到服务器、向服务器写数据、从服务器读取数据等通信。这些在Java网络编程中均有涉及。

 b) Org.apache接口

对于大部分应用程序而言JDK本身提供的网络功能已远远不够,这时就需要Android提供的Apache HttpClient了。它是一个开源项目,功能更加完善,为客户端的Http编程提供高效、最新、功能丰富的工具包支持。

 c)Android.net.*(Android网络接口)

常常使用此包下的类进行Android特有的网络编程,如:访问WiFi,访问Android联网信息,邮件等功能。

2)网络架构主要有两种模式B/S,C/S 

  B/S----》就是浏览器/服务器端模式了,通过应用层的HTTP协议通信,不需要特定客户端软件,而是需要统一规范的客户端,简而言之就是Android网络浏览器(如chrome,UcWeb,QQ浏览器等等)访问web服务器端的方式了。

 C/S-----》就客户端/服务器端模式,通过任意的网络协议通信,需要特定的客户端软件。

3)服务器端返回客户端的内容有三种方式:

a)以HTML代码的形式返回。

b)以XML字符串的形式返回,做Android开发时这种方式比较多。返回的数据需要通过XML解析(SAX、DOM,Pull,等)器进行解析(必备知识)。

c)以json对象的方式返回。


Android的网络编程分为2种:基于http协议的,和基于socket的

一、HTTP协议

  基于TCP/IP协议之上的协议

1.1HttpURLConnection连接URL
1)创建一个URL对象

URL url = new URL(http://www.baidu.com);

2)利用HttpURLConnection对象从网络中获取网页数据

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

3)设置连接超时

conn.setConnectTimeout(6*1000);

4)对响应码进行判断

if (conn.getResponseCode() != 200)    //从Internet获取网页,发送请求,将网页以流的形式读回来

throw new RuntimeException("请求url失败");

5)得到网络返回的输入流

InputStream is = conn.getInputStream();
6)String result = readData(is, "GBK"); //文件流输入出文件用outStream.write
7)conn.disconnect();

总结:
--记得设置连接超时,如果网络不好,Android系统在超过默认时间会收回资源中断操作.
--返回的响应码200,是成功.
--在Android中对文件流的操作和Java SE上面是一样的.
--在对大文件的操作时,要将文件写到SDCard上面,不要直接写到手机内存上.
--操作大文件是,要一遍从网络上读,一遍要往SDCard上面写,减少手机内存的使用.这点很重要,面试经常会被问到.
--对文件流操作完,要记得及时关闭.


1.2向服务器端发送请求参数
步骤:
1)创建URL对象:URL realUrl = new URL(requestUrl);
2)通过HttpURLConnection对象,向网络地址发送请求

HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
3)设置容许输出:conn.setDoOutput(true);
4)设置不使用缓存:conn.setUseCaches(false);
5)设置使用POST的方式发送:conn.setRequestMethod("POST");
6)设置维持长连接:conn.setRequestProperty("Connection", "Keep-Alive");
7)设置文件字符集:conn.setRequestProperty("Charset", "UTF-8");
8)设置文件长度:conn.setRequestProperty("Content-Length", String.valueOf(data.length));
9)设置文件类型:conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");

10)设置HTTP请求头

conn.setRequestProperty("Accept“,” image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");

设置语言:conn.setRequestProperty("Accept-Language“,"zh-CN");

conn.setRequestProperty("

conn.setRequestProperty("
11)以流的方式输出.
总结:
--发送POST请求必须设置允许输出
--不要使用缓存,容易出现问题.
--在开始用HttpURLConnection对象的setRequestProperty()设置,就是生成HTML文件头.

1.3.向服务器端发送xml数据(也称为实体Entity)
XML格式是通信的标准语言,Android系统也可以通过发送XML文件传输数据.
1)将生成的XML文件写入到byte数组中,并设置为UTF-8:byte[] xmlbyte = xml.toString().getBytes("UTF-8");
2)创建URL对象,并指定地址和参数:URL url = new URL( http://localhost:8080/itcast/contanctmanage.do?method=readxml );
3)获得链接:HttpURLConnection conn = (HttpURLConnection) url.openConnection();
4)设置连接超时:conn.setConnectTimeout(6* 1000);
5)设置允许输出conn.setDoOutput(true);
6)设置不使用缓存:conn.setUseCaches(false);
7)设置以POST方式传输:conn.setRequestMethod("POST");           
8)维持长连接:conn.setRequestProperty("Connection", "Keep-Alive");
9)设置字符集:conn.setRequestProperty("Charset", "UTF-8");
10)设置文件的总长度:conn.setRequestProperty("Content-Length", String.valueOf(xmlbyte.length));
11)设置文件类型:conn.setRequestProperty("Content-Type", "text/xml; charset=UTF-8" );
12)以文件流的方式发送xml数据:outStream.write(xmlbyte);
总结:
--我们使用的是用HTML的方式传输文件,这个方式只能传输一般在5M一下的文件.
--传输大文件不适合用HTML的方式,传输大文件我们要面向Socket编程.确保程序的稳定性
--将地址和参数存到byte数组中:byte[] data = params.toString().getBytes();

1.4 利用Apache的HttpClient实现Android客户端发送实体Entity

 以上为直接利用HTTP协议来实现的,其实Android已经集成了第三方开源项目-------org.apache.http.client.HttpClient,可以直接参考它提供的API使用。

HTTP clients encapsulate a smorgasbord of objects required to execute HTTP requests while handling cookies, authentication, connection management, and other features. Thread safety of HTTP clients depends on the implementation and configuration of the specific client.

使用POST方法进行参数传递时,需要使用NameValuePair来保存要传递的参数。另外,还需要设置所使用的字符集。

二、基于Socket通信

  Socket编程比基于URL的网络编程提供了更高的传输效率,更强大的功能和更灵活的控制。在Java中已经是层次最低的网络编程接口,在Java中要直接操作协议中更低的层次,那就只有使用JNI了,那基本属于本地语言的范畴。



三、其它网络相关技术

3.1、Android WebView控件

   在android app 中嵌入网页的形式。

     此外,通过webview可以实现HTML<------->javascript<-------->Android Java 交互,访问本地手机硬件。

 例如:

1)   webview.addJavascriptInterface(Object obj, String interfaceName))方法,  让Java方法可以在javascript中被调用;

void addJavascriptInterface(Object obj, String interfaceName)
Use this function to bind an object to JavaScript so that the methods can be accessed from JavaScript.
2)Java中调用Javascript脚本中的方法

  webview.loadUrl("javascript:show('"+json+"')");//调用js的show方法


3.2基于SOAP协议与Webservice网络交互 ------------KSoap2
   
简单对象访问协议,简单对象访问协议(SOAP)是一种轻量的、简单的、基于 XML 的协议。

通过第三方提供的架包ksoap2-Android-assembly-2.4-jar-with-dependencies.jar,我们可以向服务器进行请求调用自己需要的服务。

3.3 实现服务器推送

通过建立持久连接的方法,服务器端发送信息给手机Android用户。

方法一:MQTT协议(实例android+php)

1、服务器端需下载安装IBM的 Really Small Message Broker (RSMB)(MQTT协议代理),并运行broker;

下载地址:http://www.alphaworks.ibm.com/tech/rsmb

2、PHP服务器端使用SAM 针对MQTT写的PHP库(下载链接为Tokudu PHPMQTT通信项目),其中send_mqtt.php是一个通过POST接收消息并且通过SAM将消息发送给RSMB的PHP脚本;

3、实例下载:

说明:http://tokudu.com/2010/how-to-implement-push-notifications-for-android/

android客户端:https://github.com/tokudu/AndroidPushNotificationsDemo

php服务器端:https://github.com/tokudu/PhpMQTTClient

 

方法二:XMPP协议(实例android+jsp)

XMPP : The Extensible Messaging and Presence Protocol (可扩展通讯和表示协议) XMPP 以 Jabber 协议为基础,而 Jabber 是即时通讯中常用的开放式协议。

下载地址: http://sourceforge.net/projects/androidpn/files/

解压服务器端,点击bin/run.bat运行,访问:http://127.0.0.1:7070/index.do,就可以看服务器端的管理页面,用这个管理页面,就要向客户端push消息。


方法三:使用APNS (Android Push Notification Service)

http://www.push-notification.org/

APNS (Android Push Notification Service) 是一种在 android 上轻松实现 push notification 的功能的解决方案. 只需申请一个 API Key, 经过简单的步骤即可实现 push notification 的功能.



3.4 PhoneGap 

   提到移动3G时代网络应用,不得不提一下PhoneGap了。

   phonegap利用HTML,CSS,javascript, 支持Android、iPhone,Windows Phone、Palm OS、Sybian....

   如果考虑开发一款应用,适用于大多数智能手机,phonegap是可以考虑的开发框架之一。







相关链接:

1.封装一个HTTP请求的辅助类,http://blog.csdn.net/ihrthk/article/details/7739834




Android各种网络协议,mark一下下次不用再翻以前的工程

Soap协议

[java]  view plain  copy
  1. public static Doctor doctorLogin(String loginName, String password, String terminal) throws AppException {  
  2.         Doctor user = null;  
  3.         String methodName = "doctorLogin";  
  4.         try {  
  5.             // 创建soap对象  
  6.             SoapObject soapObject = new SoapObject(Constant.loginNamespace, methodName);  
  7.             // 添加参数  
  8.             soapObject.addProperty("arg0", loginName);  
  9.             soapObject.addProperty("arg1", password);  
  10.             soapObject.addProperty("arg2", terminal);  
  11.   
  12.             // 设置连接参数  
  13.             HttpTransportSE hse = new HttpTransportSE(Constant.loginUrl, Constant.OverTime);  
  14.             hse.debug = true;  
  15.             SoapSerializationEnvelope sse = new SoapSerializationEnvelope(SoapEnvelope.VER11);  
  16.             sse.bodyOut = soapObject;  
  17.             sse.dotNet = false;  
  18.             hse.call(null, sse);  
  19.             String result = sse.getResponse().toString();  
  20.   
  21.             // 解析结果  
  22.             JSONObject jsonObject = new JSONObject(result);  
  23.             Boolean resultTag = jsonObject.getBoolean("resultTag");  
  24.             if (resultTag) {  
  25.                 // 使用Gson 实现对Json字符的解析  
  26.                 String userinfo = jsonObject.getString("doctor");  
  27.                 GsonBuilder builder = new GsonBuilder();  
  28.                 Gson gson = builder.create();  
  29.                 user = gson.fromJson(userinfo, Doctor.class);  
  30.   
  31.             } else {  
  32.                 String exMsg = jsonObject.getString("msg");  
  33.                 loginException = exMsg;  
  34.                 AppException mAppException = new AppException(exMsg);  
  35.                 throw mAppException;  
  36.             }  
  37.         } catch (Exception e) {  
  38.             AppException mAppException = new AppException(e);  
  39.             throw mAppException;  
  40.         }  
  41.         return user;  
  42.     }  

http 协议与服务器通信

以下是上次用到的mark一下

[java]  view plain  copy
  1. public List getDoctoradviceList(String persionID,String beginTime,String endTime) throws Exception {  
  2.         List list = null;  
  3.         StringBuffer mBuffer = new StringBuffer();  
  4.         mBuffer.append(persionID);  
  5.         mBuffer.append("/");  
  6.         mBuffer.append(beginTime.replace(" ""%20"));  
  7.         if(D)Log.d(TAG,"beginTime"+ beginTime);  
  8.         mBuffer.append("/");  
  9.         mBuffer.append(endTime.replace(" ""%20"));  
  10.         if(D)Log.d(TAG, "endTime"+ endTime);  
  11.         HttpGet requstGet = new HttpGet(Constant.getDoctoradvicAddress+mBuffer.toString());  
  12.         requstGet.setHeader("Accept""application/json");  
  13.         requstGet.setHeader("Content-type""application/json;charset=UTF-8");  
  14.         HttpResponse mResponse = new DefaultHttpClient().execute(requstGet);  
  15.         //获取网络连接状态  
  16.         int intId = mResponse.getStatusLine().getStatusCode();  
  17.         String responsStr = null;  
  18.         HttpEntity mEntity = mResponse.getEntity();  
  19.         if (mEntity != null) {  
  20.             InputStream mInputStream = mEntity.getContent();  
  21.             responsStr = StrUtil.convertStreamToString(mInputStream);  
  22.             if (D) Log.d(TAG, "医生建议查询:" + responsStr);  
  23.             if (intId == 200) {  
  24.                 GsonBuilder gsonb = new GsonBuilder();  
  25.                 Gson gson = gsonb.create();  
  26.                 list = gson.fromJson(responsStr, new TypeToken>(){}.getType());  
  27.             }else{  
  28.                 GsonBuilder gsonb = new GsonBuilder();  
  29.                 Gson gson = gsonb.create();  
  30.                 Fault f = gson.fromJson(responsStr, Fault.class);  
  31.                 throw new AppException(f.message);  
  32.             }  
  33.         }  
  34.           
  35.         return list;  
  36.     }  


http://www.cnblogs.com/hanyonglu/archive/2012/02/19/2357842.html  由于http用的少,特意转载了一篇以备理解

本示例以Servlet为例,演示Android与Servlet的通信

众所周知,Android与服务器通信通常采用HTTP通信方式和Socket通信方式,而HTTP通信方式又分get和post两种方式。至于Socket通信会在以后的博文中介绍。

HTTP协议简介: 

HTTP (Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种协议。 

 

HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。  在HTTP 1.0中,客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。  在HTTP 1.1中则可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。

 

由于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”、“无状态”,要保持客户端程序的在线状态,需要不断地向服务器发起连接请求。通常的做法是即使不需要获得任何数据,客户端也保持每隔一段固定的时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复,表明知道客户端“在线”。若服务器长时间无法收到客户端的请求,则认为客户端“下线”,若客户端长时间无法收到服务器的回复,则认为网络已经断开。 

基于HTTP1.0协议的客户端在每次向服务器发出请求后,服务器就会向客户端返回响应消息,在确认客户端已经收到响应消息后,服务端就会关闭网络连接。在这个数据传输过程中,并不保存任何历史信息和状态信息,因此,HTTP协议也被认为是无状态的协议。

  HTTP1.1和HTTP1.0相比较而言,最大的区别就是增加了持久连接支持。当客户端使用HTTP1.1协议连接到服务器后,服务器就将关闭客户端连接的主动权交还给客户端;也就是说,只要不调用Socket类的close方法关闭网络连接,就可以继续向服务器发送HTTP请求。

 

HTTP连接使用的是“请求—响应”的方式(2次握手),不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。而Socket连接在双方建立起连接后就可以直接进行数据的传输

 

 HTTP协议的特点:

 支持B/S及C/S模式;

简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。

灵活:HTTP 允许传输任意类型的数据对象。正在传输的类型由Content-Type 加以标记;

无状态:HTTP 协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。

 

HTTP协议请求方法: 

请求行中包括了请求方法,解释如下:

GET 请求获取Request-URI 所标识的资源;

POST 在Request-URI 所标识的资源后附加新的数据;

HEAD 请求获取由Request-URI 所标识的资源的响应消息报头 

PUT 请求服务器存储一个资源,并用Request-URI 作为其标识

DELETE 请求服务器删除Request-URI 所标识的资源;

TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断

CONNECT 保留将来使用

OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求

Get与Post请求区别: 

Post请求可以向服务器传送数据,而且数据放在HTML HEADER内一起传送到服务端URL地址,数据对用户不可见。而get是把参数数据队列加到提交的URL中,值和表单内各个字段一一对应, 例如(http://www.baidu.com/s?w=%C4&inputT=2710)

get 传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为80KB,IIS5中为100KB。

get安全性非常低,post安全性较高。

项目结构图: 

 

 

  get方式:

          get机制用的是在URL地址里面通过?号间隔,然后以name=value的形式给客户端传递参数。所以首先要在Android工程下的AndroidGetTest.java中onCreate方法定义好其URL地址以及要传递的参数,然后通过URL打开一个HttpURLConnection链接,此链接可以获得InputStream字节流对象,也是往服务端输出和从服务端返回数据的重要过程,而若服务端response.getInputStream.write()往andorid返回信息时候,就可以通过InputStreamReader作转换,将返回来的数据用BufferReader显示出来。

具体代码如下:

          Servlet端接收数据并返回通知: 

 

 

   Android端发送消息并接收Servlet返回的消息:

 

 post方式:

         post传输方式不在URL里传递,也正好解决了get传输量小、容易篡改及不安全等一系列不足。主要是通

过对 HttpURLConnection的设置,让其支持post传输方式,然后在通过相关属性传递参数(若需要传递中文字符,则可以通过URLEncoder编码,而在获取端采用URLDecoder解码即可) 

 

 




其中通信的过程中需要文件的上传、下载会以 IO 流的方式传输

下载一张图片

private void getNetWorkImage() {
    new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                URL imageUrl = new URL("https://www.baidu.com/img/bdlogo.png");
                HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();
                conn.setConnectTimeout(10000);
                conn.setRequestMethod("GET");
                if(conn.getResponseCode() == 200) {
                    InputStream is = conn.getInputStream();
                    Bitmap bitmap = BitmapFactory.decodeStream(is);
                    Message msg = mHandle.obtainMessage();
                    msg.what = 1;
                    msg.obj = bitmap;
                    mHandle.sendMessage(msg);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();

}


最后还找到了一个关于写网络协议挺好的博客,其中写了各种协议,内容挺详细的,值的一看,这里我附上地址:
http://www.cnblogs.com/devinzhang/category/349642.html



你可能感兴趣的:(android)