android n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
第五章. Android 网络编程 PowerPoint Presentation
Download Presentation
第五章. Android 网络编程

Loading in 2 Seconds...

play fullscreen
1 / 34

第五章. Android 网络编程 - PowerPoint PPT Presentation


  • 188 Views
  • Uploaded on

第五章. Android 网络编程. 教学内容. 基于 Socket 网络编程 基于 HTTP 协议的网络编程 GoogleMap 使用 基于蓝牙开发. 教学重点. 基于 HTTP 协议的网络编程 基于蓝牙开发. 基于 Socket 网络编程. Socket 网络通信的组成元素 服务器,主要功能:侦听连接、接收连接、接收数据和向客户端发送数据。 客户端,主要功能:发起连接、接收数据和向服务器发送数据 Socket 网络通信的基本原理. Socket = IP ( address) + Port(server). IP 地址 : 主机标识

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about '第五章. Android 网络编程' - everly


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
slide2
教学内容
  • 基于Socket网络编程
  • 基于HTTP协议的网络编程
  • GoogleMap使用
  • 基于蓝牙开发

教学重点

  • 基于HTTP协议的网络编程
  • 基于蓝牙开发
socket
基于Socket网络编程
  • Socket网络通信的组成元素
    • 服务器,主要功能:侦听连接、接收连接、接收数据和向客户端发送数据。
    • 客户端,主要功能:发起连接、接收数据和向服务器发送数据
  • Socket网络通信的基本原理

Socket = IP(address) + Port(server)

IP地址 : 主机标识

端 口 : 服务类型

socket1

Java--Internet语言

具备强大网络通信功能

基于套接字(Socket)通信方式

流套接字

数据报套接字

TCP协议

(Transmission Control Protocol)

UDP协议

(User Datagram Protocol)

基于Socket网络通信方式
slide5
主要使用类

Java的Socket属于流式套接字通信,采用TCP协议,提供面向连接的服务,实现可靠的通信。

Java.net提供两个类,实现Socke通信:

ServerSocket -- 服务器端

Socket -- 客户端通

  • 操作TCP 套接字的发送和接收需要借助java.io包的
      • InputStream / OutputStream
  • 完成,分别通过方法实现:
  • Socket.getInputStream() / Socket.getOutputStream()
socket serversocket
Socket/ServerSocket构造函数

ServerSocket()

创建非绑定服务器套接字

ServerSocket(int port)

创建绑定到特定端口的服务器套接字

ServerSocket(int port, int backlog)

利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号

ServerSocket(int port, int backlog, InetAddress bindAddr)

使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器

Socket()

通过系统默认类型的 SocketImpl 创建未连接套接字

Socket(InetAddress address, int port)

创建一个流套接字并将其连接到指定 IP 地址的指定端口号

Socket(InetAddress address, int port, InetAddress localAddr, int localPort)

创建一个套接字并将其连接到指定远程端口上的指定远程地址

Socket(String host, int port)

创建一个流套接字并将其连接到指定主机上的指定端口号

Socket(String host, int port, InetAddress localAddr, int localPort)

创建一个套接字并将其连接到指定远程主机上的指定远程端口

socke

服务端

客户端

一个ServerSocket对象和一个Socket对象

访问监听

ServerSocket (port)

创建ServiceSocke对象,提供TCP连接服务

ServerSocket

对象

一个Socket对象

accept ()

在指定的端口监听客户端请求联结创建

Socket (host,port)

创建Socket对象

向指定主机端口发出连接请求

联结成功

获得已连接的Socket对象

t

e

k

c

o

S

InputStream

获得Socket对象输入流

InputStream

获得Socket对象输入流

Socket对象

OutputStream

获得Socket对象输出流

OutputStream

获得Socket对象输出流

通过流传输数据

Socket.close()

关闭TCP连接

Socket.close()

关闭TCP连接

ServerSocket

对象

ServiceSocket.close()

停止提供TCP连接服务

Socke通信机制
socke1
Socke通信机制

Server端

Client端

service = ServerSocket (port_number)

创建service对象,以TCP服务实现端口监听

socket = ServerSocket.accept()

创建socke对象, 接收用户访问请求

(1)

建立连接

Socket = Socket (port_number)

创建socke对象,建立连接,发送访问请求

OutputStream Socket对象输出流

InputStream Socket对象输入流

通过socke对象,实现与Servert端数据传输

InputStream Socket对象输入流OutputStream Socket对象输出流

通过socke对象实现与Client端数据传输

(2)

数据通讯

socket.close()

关闭Socke关闭结束与Client端的连接

service. close()

关闭监听程序

socket.close()

关闭Socke

结束与Server端的连接

(3)

拆除连接

slide10
客户端
  • 开启INTERNET
  • 布局界面(Main.xml)
  • 获取资源(EditText,Button,TextView)
  • Socket通信
  • 数据读写(DataInputStream/DataOutputStream)
slide11

客户端主要代码:

public void onClick(View v) {

Socket s = null;

DataOutputStream dout = null;

DataInputStream din = null;

if(v == button1){//点击的是按钮

try {

s = new Socket("192.168.9.102", 8888);//连接服务器

dout = new DataOutputStream(s.getOutputStream());//得到输出流

din = new DataInputStream(s.getInputStream());//得到输入流dout.writeUTF(editText.getText().toString());//向服务器发送消息textView.setText("服务器发来的消息:" + din.readUTF());//接收服务器发来的消息

}

slide12

catch (Exception e) {

e.printStackTrace();//打印异常信息

} finally {

try{

if(dout != null){

dout.close();//关闭输入流

}

if(din != null){

din.close();//关闭输入流

}

if(s != null){

s.close();//关闭Socket连接

}

}

catch(Exception e){ e.printStackTrace();//打印异常信息

}

}

}

}

slide13
服务器(例子)
  • ServerSocket
  • Accept
  • DataInputStream/DataOutputStream
  • Read/Write
slide14

服务器端主要代码:

ServerSocket ss = null;//ServerSocket的引用

Socket s = null;//Socket的引用

DataInputStream din = null;

DataOutputStream dout = null;

try{

ss = new ServerSocket(8888);//监听到8888端口

System.out.println("已监听到8888端口!");

}

catch(Exception e){

e.printStackTrace();//打印异常信息

}

while(true){

try{

s = ss.accept();//等待客户端连接

din = new DataInputStream(s.getInputStream());

dout = new DataOutputStream(s.getOutputStream());//得到输入输出流

String msg = din.readUTF();//读一个字符串

System.out.println("ip: " + s.getInetAddress());//打印客户端IP

System.out.println("msg: " + msg);//打印客户端发来的消息

System.out.println("====================");

dout.writeUTF("Hello Client!");//向客户端发送消息

}

catch(Exception e){

e.printStackTrace();//打印异常信息

}

slide15
基于HTTP协议的网络编程

统一资源定位器URL:

URL(Uniform Resource Locator)是一致资源定位器的简称,它表示Internet上某一资源的地址。通过URL我们可以访问Internet上的各种网络资源,比如最常见的WWW,FTP站点。浏览器通过解析给定的URL可以在网络上查找相应的文件或其他资源。

URL的组成

protocol://resourceName

  协议名(protocol)指明获取资源所使用的传输协议,如http、ftp、gropher、file等,资源名(resourceName)则应该是资源的完整地址,包括主机名、端口号、文件名或文件内部的一个引用。例如:

  http://www.sun.com/ 协议名://主机名

  http://home.netscape.com/home/welcome.html 协议名://机器名+文件名

  http://www.gamelan.com:80/Gamelan/network.html#BOTTOM 协议名://机器名+端口号+文件名+内部引用.

slide16

创建一个URL

为了表示URL, java.net中实现了类URL。我们可以通过下面的构造方法来初始化一个URL对象:

(1) public URL (String spec);

(2) public URL(URL context, String spec);

(3) public URL(String protocol, String host, String file);

(4) public URL(String protocol, String host, int port, String file);

解析一个URL

一个URL对象生成后,其属性是不能被改变的,但是我们可以通过类URL所提供的方法来获取这些属性

从URL读取WWW网络资源

当我们得到一个URL对象后,就可以通过它读取指定的WWW资源。

slide17

通过URLConnetction连接WWW

通过URL的方法openStream(),我们只能从网络上读取数据,如果我们同时还想输出数据,例如向服务器端的CGI程序发送一些数据,我们必须先与URL建立连接,然后才能对其进行读写,这时就要用到类URLConnection了。CGI是公共网关接口(Common Gateway Interface)的简称,它是用户浏览器和服务器端的应用程序进行连接的接口,有关CGI程序设计,请读者参考有关书籍。

  类URLConnection也在包java.net中定义,它表示Java程序和URL在网络上的通信连接。当与一个URL建立连接时,首先要在一个URL对象上通过方法openConnection()生成对应的URLConnection对象。如果连接过程失败,将产生IOException.

slide18

URLConnection ucon = null;

BufferedInputStream bin = null;

ByteArrayBuffer bab = null;

try {

URL myURL = new URL("http://www.google.cn/");//初始化URL

ucon = myURL.openConnection();//打开连接

bin = new BufferedInputStream(ucon.getInputStream());//得到输入流

int current = 0;

bab = new ByteArrayBuffer(1000);

while((current=bin.read()) != -1){

bab.append((char)current);//将收到的信息添加到ByteArrayBuffer中

}

} catch (Exception e) {

e.printStackTrace();//打印异常信息

}

slide19

finally {

try{

if(bin != null){

bin.close();//关闭输入流

}

}

catch(Exception e){

e.printStackTrace();//打印异常信息

}

}

textView.setText(EncodingUtils.getString(bab.toByteArray(), "UTF-8"));//设置textView中的内容

scrollView.addView(textView);//将textView添加到scrollView中this.setContentView(scrollView);//设置当前显示的用户界面为scrollView

slide20
解析XML的两种主要方式

DOM方式

DOM是基于树形结构的的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树、检索所需数据。分析该结构通常需要加载整个文档和构造树形结构,然后才可以检索和更新节点信息。

由于DOM在内存中以树形结构存放,因此检索和更新效率会更高。但是对于特别大的文档,解析和加载整个文档将会很耗资源。

SAX方式

SAX(Simple API for XML)解析器是一种基于事件的解析器,它的核心是事件处理模式,主要是围绕着事件源以及事件处理器来工作的。当事件源产生事件后,调用事件处理器相应的处理方法,一个事件就可以得到处理。在事件源调用事件处理器中特定方法的时候,还要传递给事件处理器相应事件的状态信息,这样事件处理器才能够根据提供的事件信息来决定自己的行为。

SAX解析器的优点是解析速度快,占用内存少。非常适合在Android移动设备中使用。

slide21
XML解析
  • XML文件的基本格式
  • XML解析方式
    • DOM:树型结构-支持 Document Object Model (DOM) 的解析器
    • SAX:事件驱动-支持 Simple API for XML (SAX) 的解析器
slide22
XML文件的基本格式

<?xml version="1.0"?>

<!DOCTYPE movies

[

<!ELEMENT movies (movie+)>

<!ELEMENT movie (title,actor+,rating)>

<!ELEMENT title (#PCDATA)>

<!ELEMENT actor (#PCDATA)>

<!ELEMENT rating (#PCDATA)>

<!ATTLIST movie type CDATA #IMPLIED>

]>

<movies>

<movie type=“生活片”>

……

</movie>

</movies>

  • XML 声明
  • 创建DOCTYPE声明
  • 创建实体声明
  • 创建根元素
  • 创建 XML 代码
dom xml
DOM解析XML

DOM中的关键类是Node,Document,Element,NodeList,Attr。

  • Node代表结构中的一个节点。这里所指的节点可以是文档 的任何一个部分;
  • Document代表整个文档,整个文档也可以被视为一个节点, 也即Document类是由Node派生而来的;
  • Element表示任何XML元素; 同样这个类也是由Node派生来的。
  • Node类包含了一个称为childNodes的属性,这个属性的类型 是NodeList。
  • Attr代表一个元素的属性;
slide24
DOM关键类
  • Node属性(用来帮助完成对DOM树的遍历):
    • nodeType 对象类型的代码表示;
    • parentNode 当前Node对象的父节点;
    • childNodes 当前Node对象的子节点列表,它是NodeList类型;
    • firstChild Node对象的第一个子节点
    • lastChild Node对象的最后一个子节点;
    • previousSibling 紧邻当前节点的前驱Node对象;
    • nextSibling 紧邻当前节点的后继Node对象;
    • attributes 属性列表(若当前Node对象具有属性)
  • 以下为操作下层对象的属性:
    • nodename Node的名称(若有名称空间前缀,也将包含在其中);
    • localName/baseName 名称中的本地部分;
    • namespaceURI 名称空间的URI;
    • prefix 名称空间前缀;
    • nodeValue Node的值;
slide25
DOM关键类
  • NodeList

是一个包含Node列表的DOM对象。

NodeList有两个属性:

    • length 列表中的节点数;
    • item(i) 访问列表中的第i个节点的方法;
  • NamedNodeMap

是一个具有名称的节点列表,支持NodeList的属性和方法。

除了length和item(i)外,它还支持以下方法:

    • getNamedItem()/getNamedItemNS()/getQualifiedItem()根据输入节点的名称返回相应的节点;
    • setNamedItem()/setNamedItemNS()根据给定的节点名称设置节点;
    • removeNamedItem()/removeNamedItemNS()根据给定的节点名称,删掉相应的节点;
slide26
DOM关键类
  • Document对象

Document是DOM树中最顶层的元素,由Node派生而来,

增加了3种属性:

    • documentElement 从文档得到根节点;
    • implementation 定义了不需要文档参与的方法;
    • doctype 文档类型定义;
  • Element对象

Element除继承了Node的属性外,还定义了一些属性和方法:

    • tagName属性 标记名称;
    • getElementByTagName()/getElementByTagNamesNS()根据给定的标记名称返回含有该元素的所有后代的一个NodeList;
    • getAttributeNode()/getAttributeNodeNS()根据给定的标记返回一个属性节点;
slide27
DOM关键类
  • Attr对象

属性对象Attr,除继承了Node的属性之外,还定义了

下列属性:

    • name 属性名称;
    • value 属性值;
    • ownerElement 具有属性的元素;
    • specified 若属性在文档中被赋值,则它的值为true,若属性使用DTD中的默认值,则它的值为false;
dom xml1
DOM解析XML
  • 得到DOM解析器的工厂实例DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
  • 从DOM工厂获得DOM解析器DocumentBuilder dombuilder=domfac.newDocumentBuilder();
  • 把要解析的XML文档转化为输入流InputStream is=new FileInputStream("bin/library.xml");
  • 解析XML文档的输入流

Document doc=dombuilder.parse(is);

  • 得到XML文档的根节点Element root=doc.getDocumentElement();
  • 得到节点的子节点NodeListbooks=root.getChildNodes();
slide29
Xml 文件
  • <?xmlversion="1.0"encoding="UTF-8"?><persons><person><name>jak</name><sex>男</sex></person><person><name>jcy</name><sex>女</sex></person></persons>
slide30
解析代码
  • public void parsersXml() {
  • DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); //实例化一个文档构建器工厂
  • DocumentBuilder db = dbf.newDocumentBuilder(); //通过文档构建器工厂获取一个文档构建器
  • Document doc = db.parse("persons.xml"); //通过文档通过文档构建器构建一个文档实例
  • NodeList nl1 = doc.getElementsByTagName("person"); //获取所有名字为 “person”的节点
  • int size1 = nl1.getLength();
  • for (int i = 0; i < size1; i++) {
  • Node n = nl1.item(i);
  • NodeList nl2 = n.getChildNodes(); //获取 n 节点下所有的子节点。此处值得注意,在DOM解析时会将所有回车都视为 n 节点的子节点。
  • int size2 = nl2.getLength(); //因为上面的原因,在此例中第一个 n 节点有 2 个子节点,而第二个 n 节点则有 5 个子节点(因为多了3个回车)。
  • for (int j = 0; j < size2; j++) {
  • Node n2 = nl2.item(j);
  • //还是因为上面的原因,故此要处判断当 n2 节点有子节点的时才输出。
  • if (n2.hasChildNodes()) {
  • System.out.println(n2.getNodeName() + " = " +
  • n2.getFirstChild().getNodeValue());
  • } } }
  • }
sax xml
SAX解析XML
  • <?xmlversion="1.0"encoding="UTF-8"?>
  • <books>
  • <bookid="12">
  • <name>thinkinginjava</name>
  • <price>85.5</price>
  • </book>
  • <bookid="15">
  • <name>SpringinAction</name>
  • <price>39.0</price>
  • </book>
  • </books>
slide32
publicclassSaxParseServiceextendsDefaultHandler{
  • privateList<Book>books=null;
  • privateBookbook=null;
  • privateStringpreTag=null;//作用是记录解析时的上一个节点名称
  • publicList<Book>getBooks(InputStreamxmlStream)throwsException{
  • SAXParserFactoryfactory=SAXParserFactory.newInstance();
  • SAXParserparser=factory.newSAXParser();
  • SaxParseServicehandler=newSaxParseService();
  • parser.parse(xmlStream,handler);
  • returnhandler.getBooks(); }
  • @Override
  • publicvoidstartDocument()throwsSAXException{
  • books=newArrayList<Book>(); }
  • @Override
  • publicvoidstartElement(Stringuri,StringlocalName,StringqName,Attributesattributes)throwsSAXException{
  • if("book".equals(qName)){
  • book=newBook();
  • book.setId(Integer.parseInt(attributes.getValue(0))); }
  • preTag=qName;//将正在解析的节点名称赋给preTag }
  • @Override
  • publicvoidendElement(Stringuri,StringlocalName,StringqName)
  • throwsSAXException{
  • if("book".equals(qName)){
  • books.add(book);
  • book=null; }
  • preTag=null;/**当解析结束时置为空。这里很重要,例如,当图中画3的位置结束后,会调用这个方法
  • ,如果这里不把preTag置为null,根据startElement(....)方法,preTag的值还是book,当文档顺序读到图
  • 中标记4的位置时,会执行characters(char[]ch,intstart,intlength)这个方法,而characters(....)方
  • 法判断preTag!=null,会执行if判断的代码,这样就会把空值赋值给book,这不是我们想要的。*/}
  • @Override
  • publicvoidcharacters(char[]ch,intstart,intlength)throwsSAXException{
  • if(preTag!=null){
  • Stringcontent=newString(ch,start,length);
  • if("name".equals(preTag)){
  • book.setName(content);
  • }elseif("price".equals(preTag)){
  • book.setPrice(Float.parseFloat(content)); } } } }