1 / 34

第五章. Android 网络编程

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

everly
Download Presentation

第五章. Android 网络编程

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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第五章.Android网络编程

  2. 教学内容 • 基于Socket网络编程 • 基于HTTP协议的网络编程 • GoogleMap使用 • 基于蓝牙开发 教学重点 • 基于HTTP协议的网络编程 • 基于蓝牙开发

  3. 基于Socket网络编程 • Socket网络通信的组成元素 • 服务器,主要功能:侦听连接、接收连接、接收数据和向客户端发送数据。 • 客户端,主要功能:发起连接、接收数据和向服务器发送数据 • Socket网络通信的基本原理 Socket = IP(address) + Port(server) IP地址 : 主机标识 端 口 : 服务类型

  4. Java--Internet语言 具备强大网络通信功能 基于套接字(Socket)通信方式 流套接字 数据报套接字 TCP协议 (Transmission Control Protocol) UDP协议 (User Datagram Protocol) 基于Socket网络通信方式

  5. 主要使用类 Java的Socket属于流式套接字通信,采用TCP协议,提供面向连接的服务,实现可靠的通信。 Java.net提供两个类,实现Socke通信: ServerSocket -- 服务器端 Socket -- 客户端通 • 操作TCP 套接字的发送和接收需要借助java.io包的 • InputStream / OutputStream • 完成,分别通过方法实现: • Socket.getInputStream() / Socket.getOutputStream()

  6. 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) 创建一个套接字并将其连接到指定远程主机上的指定远程端口

  7. Socket/ServerSocket主要方法

  8. 服务端 客户端 一个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通信机制

  9. 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) 拆除连接

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

  11. 客户端主要代码: 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());//接收服务器发来的消息 }

  12. 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();//打印异常信息 } } } }

  13. 服务器(例子) • ServerSocket • Accept • DataInputStream/DataOutputStream • Read/Write

  14. 服务器端主要代码: 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();//打印异常信息 }

  15. 基于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 协议名://机器名+端口号+文件名+内部引用.

  16. 创建一个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资源。

  17. 通过URLConnetction连接WWW 通过URL的方法openStream(),我们只能从网络上读取数据,如果我们同时还想输出数据,例如向服务器端的CGI程序发送一些数据,我们必须先与URL建立连接,然后才能对其进行读写,这时就要用到类URLConnection了。CGI是公共网关接口(Common Gateway Interface)的简称,它是用户浏览器和服务器端的应用程序进行连接的接口,有关CGI程序设计,请读者参考有关书籍。   类URLConnection也在包java.net中定义,它表示Java程序和URL在网络上的通信连接。当与一个URL建立连接时,首先要在一个URL对象上通过方法openConnection()生成对应的URLConnection对象。如果连接过程失败,将产生IOException.

  18. 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();//打印异常信息 }

  19. 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

  20. 解析XML的两种主要方式 DOM方式 DOM是基于树形结构的的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树、检索所需数据。分析该结构通常需要加载整个文档和构造树形结构,然后才可以检索和更新节点信息。 由于DOM在内存中以树形结构存放,因此检索和更新效率会更高。但是对于特别大的文档,解析和加载整个文档将会很耗资源。 SAX方式 SAX(Simple API for XML)解析器是一种基于事件的解析器,它的核心是事件处理模式,主要是围绕着事件源以及事件处理器来工作的。当事件源产生事件后,调用事件处理器相应的处理方法,一个事件就可以得到处理。在事件源调用事件处理器中特定方法的时候,还要传递给事件处理器相应事件的状态信息,这样事件处理器才能够根据提供的事件信息来决定自己的行为。 SAX解析器的优点是解析速度快,占用内存少。非常适合在Android移动设备中使用。

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

  22. 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 代码

  23. DOM解析XML DOM中的关键类是Node,Document,Element,NodeList,Attr。 • Node代表结构中的一个节点。这里所指的节点可以是文档 的任何一个部分; • Document代表整个文档,整个文档也可以被视为一个节点, 也即Document类是由Node派生而来的; • Element表示任何XML元素; 同样这个类也是由Node派生来的。 • Node类包含了一个称为childNodes的属性,这个属性的类型 是NodeList。 • Attr代表一个元素的属性;

  24. 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的值;

  25. DOM关键类 • NodeList 是一个包含Node列表的DOM对象。 NodeList有两个属性: • length 列表中的节点数; • item(i) 访问列表中的第i个节点的方法; • NamedNodeMap 是一个具有名称的节点列表,支持NodeList的属性和方法。 除了length和item(i)外,它还支持以下方法: • getNamedItem()/getNamedItemNS()/getQualifiedItem()根据输入节点的名称返回相应的节点; • setNamedItem()/setNamedItemNS()根据给定的节点名称设置节点; • removeNamedItem()/removeNamedItemNS()根据给定的节点名称,删掉相应的节点;

  26. DOM关键类 • Document对象 Document是DOM树中最顶层的元素,由Node派生而来, 增加了3种属性: • documentElement 从文档得到根节点; • implementation 定义了不需要文档参与的方法; • doctype 文档类型定义; • Element对象 Element除继承了Node的属性外,还定义了一些属性和方法: • tagName属性 标记名称; • getElementByTagName()/getElementByTagNamesNS()根据给定的标记名称返回含有该元素的所有后代的一个NodeList; • getAttributeNode()/getAttributeNodeNS()根据给定的标记返回一个属性节点;

  27. DOM关键类 • Attr对象 属性对象Attr,除继承了Node的属性之外,还定义了 下列属性: • name 属性名称; • value 属性值; • ownerElement 具有属性的元素; • specified 若属性在文档中被赋值,则它的值为true,若属性使用DTD中的默认值,则它的值为false;

  28. 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();

  29. Xml 文件 • <?xmlversion="1.0"encoding="UTF-8"?><persons><person><name>jak</name><sex>男</sex></person><person><name>jcy</name><sex>女</sex></person></persons>

  30. 解析代码 • 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()); • } } } • }

  31. 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>

  32. 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)); } } } }

  33. Google Map

  34. 其他网络通信方式 • WIFI • Bluetooth

More Related