赵工的个人空间


专业技术部分转网页计算转业余爱好部分


 手持终端

首页 > 专业技术 > 手持终端 > Android系统的网络应用
Android系统的网络应用

网络通信包含发送方、接收方以及协议三部分,按照服务类型,网络通信可分为面向连接和无连接的方式。Android与服务器通信通常采用HTTP通信方式和Socket通信方式,也可以直接使用WebKit访问网络。

1.HTTP协议:

HTTP是Web互联网的基础,是建立在TCP协议之上的一种客户端/服务器端协议。HTTP连接的过程是客户端发送HTTP请求,等待服务器接收请求回送响应,客户端解析返回的信息。HTTP的请求方式主要有Get和Post两种方式。
Get方式是将传递的参数以数据串的方式追加到提交的URL后,传递数据量小,安全性低。Post方式是将数据放在HTTP HEADER内传送到服务器端URL地址,数据对用户不可见。
Android系统中,使用HTTP进行网络通信有HttpURLConnection和Apache HTTP客户端组件HttpClient两种。
1)HttpURLConnection接口:
如果网上某个资源URL是基于HTTP的,就可以使用java.net.HttpURLConnection进行请求和响应,每个HttpURLConnection实例都可用于生成单个请求,可以透明地共享连接到HTTP服务器的基础网络。HttpURLConnection常用的方法有:

方法

描述

InputStream getInputStream()

返回从此打开的连接读取的输入流

OutputStream getOutputStream()

返回写入到此连接的输出流

String getRequestMethod()

获取请求方法

int getResponseCode()

获取状态码,如HTTP_OK、HTTP_UNAUTHORIZED

void setRequestMethod(String method)

设置URL请求的方法

void setDoInput(boolean doinput)

设置输入流,如果使用URL连接输入,则将DoInput标志设置为true,是默认值;如果不打算使用,设为false

void setDoOutput(boolean dooutput)

设置输出流,如果使用URL连接进行输出,则将DoOutput标志设为true;如果不打算使用,设为false

void setUseCaches(boolean usecaches)

设置连接是否使用任何可用的缓存

void disconnect()

关闭连接

HttpURLConnection接口继承于URLConnection类,二者都是抽象类,无法直接实例化,其对象主要通过URL的openConnection()方法获得。代码:
URL url=new URL(URL地址)
HttpURLConnection urlConn=(httpURLConnection) url.openConnection();
在进行连接操作之前,可用对HttpURLConnection的一些属性进行设置:
urlConn.setDoOutput(true);
urlConn.setDoInput(true);
urlConn.setRequestMethod("POST");
urlConn.setUseCaches(false);
连接完成后可用关闭连接:
urlConn.disconnect();
HttpURLConnection在还有一些方法为:
·void setInstanceFollowRedirects():设置是否应该自动执行HTTP重定向。
·void setRequestProperty(String key,String value):设置一般请求属性。
HttpURLConnection请求获取URL引用的资源步骤为:
⑴创建HttpURLConnection对象;
⑵设置请求的属性和对象参数;
⑶如果是Get方式,直接调用connect()方法即可建立连接:
HttpURLConnection urlConn=(HttpURLConnection) url.openConnection();
urlConn.connect();
InputStreamReader in=new InputStreamReader(urlConn.getInputStream());
......
in.close();
urlConn.disconnect();
如果以Post方法,则需要设置请求方式为Post:
HttpURLConnection urlConn=(HttpURLConnection) url.openConnection();
urlConn.setDoInput(true);
urlConn.setDoOutput(true);
urlConn.setRequestMethod("POST");
urlConn.setUseCaches(false);
OutputStream out=httpUrlConnection.getOutputStream(); //隐式建立连接
......
out.flush();
out.close();
urlConn.disconnect();
因为需要访问网络才能进行发送或接收,因此在AndroidManifest.xml文件中需要添加网络访问权限:
<uses-permission android:name="android.permission.INTERNET"/>
2)HttpClient接口:
Apache提供了HTTP客户端组件HttpClient,它对java.net中的类进行封装和抽象,更适合在Android上开发网络应用。HttpClient而一个客户端的HTTP传输库,目的是为了让HttpClient接收和发送HTTP消息,根据请求方法的不同会用到HttpGet和HttpPost两个对象。通常使用HttpClient的子类DefaultHttpClient进行操作,用来负责处理HTTP协议的某一方面功能,如重定向或认证、保持连接等。
使用HttpClient发送请求及接收响应很简单,需要如下步骤:
⑴创建HttpClient对象:
HttpClient是一个HTTP操作的接口,因此HttpClient对象需要通过DefaultHttpClient来实例化,代码:
HttpClient client=new DefaultHttpClient();
⑵创建请求方法的实例,并指定请求URL:
如果需要发送Get请求,则创建HttpGet对象;如果需要发送Post请求,则创建HttpPost对象,代码:
Http Xxx http=new HttpXxx("URL地址"); //Xxx为Get或Post
⑶设置参数:
如果需要发送请求参数,则可调用setParams(HttpParams params)方法来添加请求参数;对于HttpPost对象而言,还可以调用setEntity(HttpEntity entity)方法来设置UrlEncodedFormEntity参数,代码为:
List<NameValuePair> params=new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username","admin"));
params.add(new BasicNameValuePair("password","123456")):
UrlEncodedFormEntity entity=new UriEncodedFormEntity(params,"utf-8");
httpPost.setEntity(entity);
⑷发送请求获取响应:
调用HttpClient对象的execute(HttpUrlRequest request)发送请求,返回HTTP响应:
HttpResponse httpResponse=client.execute(http);
⑸获取信息:
调用HttpResponse相应的方法可获取服务器返回的信息。调用HttpResponse的getEntity()方法可获取HttpEntity对象,调用EntityUtils.toString()方法可获取封装在HttpEntity对象中的服务器的响应内容,代码为:
if(httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK){
HttpEntity entity=httpResponse.getEntity();
String str_response=EntityUtils.toString(entity);
}
⑹释放连接:
无论执行方法是否成功,都必须释放连接,但对Get和Post请求方法的操作不同。Get方法的操作代码为:
String httpUrl="URL地址";
HttpClient httpclient=new DefaultHttpClient();
HttpGet httpRequest=new HttpGet(httpUrl);
HttpResponse httpResponse=httpclient.execute(httpRequest);
if(httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK){
String strResult=EntityUtils.toString(httpResponse.getEntity());
System.out.println(strResult);
}else{
System.out.println("请求错误!");
}
使用Post方法进行参数传递,需要使用NameValuePair来保存要传递的参数,另外还需要设置所使用的字符集,代码为:
String httpUrl="URL地址";
HttpPost httpRequest=new HttpPost(httpUrl);
List<NameValuePair> params=new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("param_name","param_val"));
HttpEntity httpentity=new UrlEncodedFormEntity(params,"utf-8");
httpRequest.setEntity(httpentity);
HttpClient httpclient=new DefaultHttpClient();
HttpResponse httpResponse=httpclient.execute(httpRequest);
if(httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK){
String strResult=EntityUtils.toString(httpResponse.getEntity());
System.out.println(strResult);
}else{
System.out.println("请求错误!");
}

2. WebKit:

Android提供了内置的浏览器,该浏览器使用了开源的WebKit引擎。WebKit兼容Web标准,可扩展性好。
1)WebKit组成:
Android系统中,WebKit引擎可分为Java引擎库和WebCore引擎库两部分,其中Java引擎使用JavaScript实现,负责与Android应用程序进行通信;WebCore引擎库负责处理实际的网页生成与版面元素。两个引擎之间使用JNI和Bridge相互调用。
Android对WebKit进行封装,为开发者提供丰富的接口和类,定义在android.webkit包中,通过Webkit包中提供的类,可实现Internet的访问。WebKit引擎中主要的类为:

类名

描述

BrowserFrame

BrowserFrame类是一个容器,封装了WebCore库中的Frame类,使用该类可创建WebCore中定义的Frame,并且创建该对象的事件监听方法

WebView

WebView类是WebKit模块Java层的视图类,所有需要使用Web浏览功能的Android应用程序都要创建该视图对象显示和处理请求的网络资源

HttpAuthHandler

Http认证处理类

DownloadManagerCore

DownloadManagerCore类负责管理下载网络资源,所有的网络资源下载均由该类管理。该类实例运行在WebKit线程当中,通过调用CallbackProxy对象实现与UI线程的交互

CacheLoader

缓存加载器,用于加载缓存内容

DataLoader

数据加载器,用于载入网页数据

FileLoader

文件加载器,用于将文件数据加载到Frame中

WebViewDatabase

Web视图数据库类,该类封装了WebKit引擎对SQLiteDatabase的操作

CacheSyncManager

Cache同步管理器,该类负责同步浏览器缓存数据

Network

该类封装了网络连接逻辑,为开发人员提供了更为高级的网络连接

CallbackProxy

回调代理类,该类用于UI和WebCore之间的交互。与用户相关的通知方法是在该类中定义的。当WebCore完成相应的数据处理时,则会调用Callback Proxy类中对应的方法,这些方法通过消息方式间接调用相应处理对象的处理方法

SslErrorHandler

Ssl错误处理器,该类提供了SSL错误的方法

JsResult

Js结果类,该类用于与用户交互

WebChromeClient

WebChrome客户端,该类定义了一系列事件,这些事件与浏览窗口修饰相关

CellList

CellList类定义了图片集合中的Cell,该类用于管理Cell图片的绘制、变化等

LoadListener

加载监听器,当有下载事件时,该类的DownloadFileMethod会被调用

WebViewClient

Web视图客户端类定义了页面载入、资源载入、页面访问错误等情况发生时的处理方法

DragClient

拖曳客户端类定义了与页面拖曳相关的处理

StreamLoader

包含3种类型的载入器,CacheLoader缓存加载器、DataLoader数据加载器、FileLoader文件加载器

2)WebView视图组件:
WebView是WebKit中专门用来浏览网页的视图组件,它作为应用程序的UI接口,为用户提供了一系列的网页浏览、用户交互接口,通过这些接口显示和处理请求的网络资源。
WebView支持CSS、JavaScript和HTML,并能很好地融入布局,使页面更加美观;还能够对浏览器控件进行详细的设置,例如字体、背景颜色、滚动条样式;能够捕捉到所有浏览器操作,如单击、打开或关闭URL。
WebView提供了一些常用的浏览器方法:

方法

描述

loadUrl()

打开一个指定的Web资源页面

loadData()

显示HTML格式的网页内容

getSettings()

获取WebView的设置对象

addJavascriptinterface()

将一个对象添加到JavaScript的全局对象Window中,这样可以通过window.Xxx进行调用,与JavaScript进行交互

clearCache()

清除缓存

destory()

销毁WebView

WebView继承于View,可以作为页面的一部分,但仅加载Web页面,并不包含整个浏览器,如地址栏、导航栏等,WebView控件在布局文件中描述为:
<WebView android:id="@+id/webview"
android:layout_width="match_parent" android:layout_height="match_parent"/>
要使用WebView控件访问HTML页面,需要在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.INTERNET"/>
⑴加载网页:
调用loadUrl(String url)方法加载URL对应的页面:
WebView web=(WebView)findViewbyId(R.id.webview);
web.loadUrl("http://www.dwenzhao.cn");
WebView可以加载某个URL网络地址指向的网页,也可以加载本地文件,此时的URL是文件路径,如本地文件存放在app/src/main/assets目录中,使用“file:///android_asset/XX.html”。
为了使得Android界面能达到浏览器的效果,WebView控件提供了大量的方法,如后退goback()、前进gpForward()等。
⑵WebView加载HTML代码:
当使用TextView来显示HTML文本时,TextView控件不会解析HTML标记,而是直接以字符显示输出。WebView则提供了loadData()方法对HTML字符串进行解析。WebView的loadData()方法有3个参数,依次是加载的HTML字符串、HTML代码的MIME类型、HTML代码所用的字符集。
新版本Android引入了loadDataWithBaseURL()方法,包含5个参数:
void loadDataWithBaseURL(String baseUrl,String data,String mimeType,String encoding,String historyUrl)
其中新增了指定页面的baseUrl和历史URL,baseUrl设为null则使用默认值“about blank”。
⑶WebView使用JavaScript:
当加载的页面中使用了JavaScript时,为了成功加载该页面,必须允许脚本运行。在Android应用程序中,可以直接调用WebView中的JavaScript代码,而WebView中的JavaScript也可以去调用Android应用程序。
为了使得WebView中的JavaScript与Android应用程序交互,WebView提供了WebSettings管理工具类,提供了一系列方法。getSettings()方法获取WebView设置的管理对象,setJavaScriptEnabled()方法允许加载的网页使用JavaScript。为了能够将Java定的方法供JavaScript调用,还需要为此添加绑定二者的接口,即调用addJavascriptInterface(Object object,String name)实现将Java对象暴露给JavaScript的目的,其中object为Java对象的实例,name为用户自定义的名字,是Java对象Object在JavaScript中的别名,在JavaScript中通过这个名字可以调用Java对象定义的方法。
⑷使用步骤:
要实现WebView中的JavaScript与Android应用程序交互,要经过如下步骤:
◆创建WebSettings工具类对象
WebView view=(WebView)findViewById(R.id.<WebView Id>);
WebSettings sets=view.getSettings();
◆调用setJavaScriptEnabled()方法开启使用JavaScript
sets.setJavaScriptEnabled(true);
◆调用addJavascriptInterface()方法,创建一个访问Java方法的接口
view.addJavascriptInterface(new <Objectname>(context,webview),"obj");
其中,context为当前应用程序的Context,webview是方法注入JavaScript的WebView组件,通过这两个参数,实现了初始化绑定WebView和JavaScript的Java对象。通过obj这个名字即可调用Java对象中定义的方法。

3. Socket通信:

HTTP连接使用的是“请求-响应方式”,即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据。Socket通信则是在双方建立起连接后就可以直接进行数据的传输,不需要每次由客户端向服务器发送请求。Socket是一种比较低层的网络编程方式,而且是跨平台的,可以在异构语言之间进行通信。
Socket也称为套接字,是用来描述通信链的句柄,包括IP地址和端口。通过套接字,应用程序之间可传输信息。Socket有面向连接和无连接两种传输模式,面向连接使用TCP协议,在通信两端建立通信链路,依次发送和接收数据,通信结束要释放连接;无连接模式使用UDP协议,将数据进行打包发送,接收端接收数据包的顺序与发送端发送的顺序可能不同,数据安全性不佳,但传输开销要小。
java.net包中提供了两个Socket类,java.net.Socket是客户端的Socket对应的类,java.net.Server Socket是服务器端的Socket对应的类。
1)Socket类:
Socket类的常用方法有:

方法

描述

bind(String host,int port)

将该Socket同参数localAddr指定的地址和端口绑定

InetAddress getInetAddress()

获取该Socket连接的目标主机的IP地址

synchronized int getReceiveBufferSize()

获取该Socket的接收缓冲区的大小

synchronized void close()

关闭Socket

InputStream getInputStream()

获取该Socket的输入流,这个输入流用来读取数据

boolean isConnected()

判断该Socket是否连接

boolean isOutputShundown()

判断该Socket的输出管道是否关闭

boolean isInputShundown()

判断该Socket的输入管道是否关闭

SocketAddress getLocalSocketAddress()

获取此Socket的本地地址和端口

int getPort()

获取端口号

Socket的构造方法带有2个参数,用于创建一个到主机host、端口号port的套接字,并连接到远程主机。Socket(String host,int port)
一般情况下,Socket类的工作步骤为:
⑴根据指定地址和端口创建一个Socket对象
⑵调用getInputStream()方法或getOutputStream()方法打开连接到Socket的输入/输出流
⑶客户端与服务器根据一定的协议交互,直到关闭连接
⑷关闭客户端的Socket
典型的创建客户端Socket的过程为:
try{
Socket socket=new Socket("127.0.0.1',4700);
}catch(IOException ioe){
System.out.println("Error:"+ioe);
}catch(UnknownHostException uhe){
Syetem.out.println("Error:"+uhe);
}
2)ServerSocket类:
ServerSocket类用于监听在特定端口的TCP连接。当客户端的Socket试图与服务器指定端口建立连接时,服务器被激活,判断客户程序的连接,一旦客户端与服务器建立了连接,两者之间就可以相互传送数据。ServerSocket类常用的方法有:

方法

描述

Socket accept()

等待客户端的连接,当客户端请求连接时返回一个Socket

void close()

关闭服务器Socket

SocketAddress getLocalSocketAddress()

获取此Socket的本地地址和端口

int getLocalPort()

获取端口号

InetAddress getInetAddress()

获取该Socket的IP地址

boolean isClosed()

判断连接是否关闭

void setSoTimeout(int timeout)

设置accept的超时时间

ServerSocket的构造方法只有一个端口参数:ServerSocket(int port)
一般情况下,ServerSocket类的工作步骤为:
⑴根据指定端口创建一个新的ServerSocket对象
⑵调用ServerSocket的accept()方法,在指定的端口监听到来的连接。accept()一直处于阻塞状态,直到有客户端试图建立连接,这时accept()方法返回连接客户端与服务器的Socket对象。
⑶调用getInputStream()方法或getOutputStream()方法建立与客户端交互的输入/输出流
⑷服务器与客户端根据一定的协议交互,直到关闭连接
⑸关闭服务器端的Socket
⑹回到第3步,继续监听下一次连接
典型的创建服务器端ServerSocket的过程代码为:
ServerSocket server=null;
try{
server=new ServerSocket(4700);
}catch(IOException e){
System.out.println("can not listen to:"+ioe);
}
Socket socket=null;
try{
socket=server.accept();
}catch(IOException e){
Syetem.out.println("Error:"+e);
}
3)使用基于TCP协议的Socket进行通信:
TCP是Transmission Control Protocol的缩写,即传输控制协议,这是一种面向连接的、可靠的、基于字节流的传输层通信协议。应用层向传输层发送用于网络间传输的数据流,TCP把数据流分割成适当长度的报文段,之后TCP把结果包传给IP层,由它通过网络将包传送给接收端实体的TCP层。
当两个用户端进行连接时,TCP协议会让它们建立一个用于收发数据的虚拟链路,由TCP协议负责收集信息,通过这个链路可以进行数据传输。TCP提供超时重发、丢弃重复数据、检验数据、流量控制等功能,确保数据能从一端传到另一端。
当Java建立了两个Socket对象时,分别代表链路两端实体的通信接口,通过Socket产生I/O流进行网络通信,此时这两个通信实体并没有服务器端和客户端的区分。在虚拟链路尚未建立起来之前,需要有一个通信实体先主动,主动接收来自其他通信实体的连接请求。Java提供了ServerSocket类,用于监听来自客户端的Socket连接,如果没有连接请求,则一直处于等待状态。
基于TCP的Socket通信步骤为:
⑴创建TCP的Socket服务器端。
利用ServerSocket创建服务器端,可以通过以下构造器:
·ServerSocket(int port):指定端口号来创建ServerSocket对象
·ServerSocket(int port,int backlog):增加了改变连接队列的参数backlog
·ServerSocket(int port,int backlog,InetAddress localAddr):增加了IP地址参数localAddr,用来指定将ServerSocket绑定到指定的IP地址
⑵等待客户端请求。
一个服务器端可以接收多个客户端请求,即循环调用accept()方法不断接收客户端请求:
ServerSocket server=new ServerSocket(50000);
while(true){Socket socket=server.accept();}
⑶服务器端接收请求,返回响应。
accept()方法在没有数据进行接收时处于堵塞状态,一旦接收到数据,就可以通过InputStream读取接收的数据,通过OutStream返回响应数据。
⑷客户端发送请求,获取返回信息。
服务器端通过创建ServerSocket对象来等待客户端请求,而客户端创建一个指定服务器端IP地址和端口号的Socket对象,通过InputStream读取数据、OutputStream写入数据,即可实现使用TCP协议进行Socket数据传输。
4)使用基于UDP的Socket通信:
UDP是User Datagram Protocol的缩写,即用户数据报协议,是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。UDP只负责将传送给IP层的报文发送出去,而无法得知其是否安全完整到达目的地以及到达的次序。因为UDP在传输数据包前不用在客户端和服务器之间建立一个连接,且没有超时重发等机制,因此传输速度很快。
Java使用DatagramSocket代表UDP协议的Socket,DatagramSocket不维护状态,不能产生IO流,唯一作用就是接收和发送数据包。Java使用DatagramPacket来代表数据包,Datagram Socket接收和发送的数据都是通过DatagramPacket对象完成的。
使用DatagramSocket创建UDP服务器端步骤为:
⑴创建DatagramSocket对象。
创建DatagramSocket对象可通过如下构造器:
·DatagramSocket():创建一个DatagramSocket示例,并将该对象绑定到本机默认IP地址,从本机所有可用端口中随机选择的某个端口
·DatagramSocket(int port):创建一个DatagramSocket实例,并将该对象绑定到本机默认IP地址、指定端口
·DatagramSocket(int port,InetAddress laddr):创建一个DatagramSocket实例,并将该对象绑定到指定IP地址、指定端口
⑵创建DatagramPacket对象:
DatagramPacket是数据包的载体,该对象的实例化需要两个参数,用于描述接收的数据包及其长度,代码为:
byte data[]=new byte[1024];
DatagramPacket packet=new DatagramPacket(data,data.length);
⑶接收数据。
使用DatagramSocket的receive方法可以接收客户端发送的数据,receive()与serversocket的accept()类似,在没有数据进行接收时处于堵塞状态。接收到的数据封装在DatagramPacket中,通过调用相应的方法可以将数据读取出来,getData()方法用来获取数据缓冲区,getOffset()方法用来获取数据起始位置,getLength()方法用来获取数据长度。代码为:
DatagramSocket socket=new DatagramSocket(10000);
byte data[]=new byte[4*1024];
DatagramPacket packet=new DatagramPacket(data,data.length);
socket.receive(packet);
String result=new String(packet.getData(),packet.getOffset(),packet.getLength());
使用DatagramSocket创建UDP客户端的步骤为:
⑴客户端需要创建指定监听端口的DatagramSocket对象。
创建方式与服务器端创建DatagramSocket对象相同,需要指定端口号,代码为:
DatagramSocket socket=new DatagramSocket(10000);
⑵创建InetAddress对象。
创建InetAddress对象,通过该对象的getByName()方法将IP地址字符串转化为要发送请求的网络地址。代码为:
InetAddress serverAddress=InetAddress.getByName("192.168.1.101");
⑶创建DatagramPacket对象。
首先定义一个字符串表示要发送的信息,并将其存储在字节数组中。然后创建一个Datagram Packet对象,与服务器端的DatagramPacket不同,发送数据时创建DatagramPacket对象需要4个参数,分别为数据包、数据包长度、要发送的地址以及端口号,代码为:
DatagramSocket socket=new DatagramSocket(10000);
InetAddress serverAddress=InetAddress.getByName("192.168.1.101");
String str="[send message]";
byte data[]=str.getBytes();
DatagramPacket packet=new DatagramPacket(data,data.length,serverAddress,10000);
⑷发送数据。
调用DatagramSocket对象的send()方法以发送数据。代码为:
socket.send(packet);


Copyright@dwenzhao.cn All Rights Reserved   备案号:粤ICP备15026949号
联系邮箱:dwenzhao@163.com  QQ:1608288659