Android应用开发基础教程(微课版) 课件 第9、10章 网络编程、高级应用_第1页
Android应用开发基础教程(微课版) 课件 第9、10章 网络编程、高级应用_第2页
Android应用开发基础教程(微课版) 课件 第9、10章 网络编程、高级应用_第3页
Android应用开发基础教程(微课版) 课件 第9、10章 网络编程、高级应用_第4页
Android应用开发基础教程(微课版) 课件 第9、10章 网络编程、高级应用_第5页
已阅读5页,还剩74页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Andriod应用开发基础教程第9章网络编程9.1UDP、TCP、HTTP协议基础UDP是一种无连接的、不可靠的协议,它不会对数据进行确认或重传,也不会进行数据排序。UDP不需要建立连接,以报文(Datagram)为单位来收发数据,数据包可以直接发送,每个UDP包都是独立的,并且可能会在传输过程中丢失、重复、乱序。因此,UDP适用于需要快速传输数据,而对数据可靠性要求不高的应用场景,如网络直播、在线游戏、IP电话、视频会议等。TCP是一种面向连接的、可靠的协议,它为数据包的传输提供了确认、重传、数据排序和流量控制等功能,保证了数据的可靠性。TCP通过三次握手来建立连接,四次挥手来终止连接。在传输数据时,TCP将数据分成多个包进行传输,每个包都有自己的编号和校验,接收方会对每个包进行确认,如果某个包没有被确认,发送方会重新发送这个包,直到接收方确认为止。TCP适用于需要可靠传输的应用场景,如文件传输、Web浏览器、电子邮件等。以人与人之间的通信为例,UDP协议就相当于是写信给对方,寄出去信件之后不能知道对方是否收到信件,信件内容是否完整,也不能得到及时反馈,而TCP协议就像是打电话通信,在这一系列流程都能得到及时反馈,并能确保对方及时接收到。HTTP协议全称为HypertextTransferProtocol,即超文本传输协议,是互联网上应用最为广泛的一种网络传输协议。HTTP协议定义了客户端(Browser)与服务器之间的通信规范,以实现对各种资源(如HTML页面、图像、音频、视频等)的传输和访问。HTTP协议是一个无状态的应用层协议,基于请求响应模式且请求和响应都是一条文本消息,再则HTTP协议是一个无连接协议,所以每个请求都是独立的,服务器处理请求后立即关闭连接。9.2Socket通信Socket就是两个应用程序通过一个双向的通信连接实现数据的交换,连接的一段就是一个Socket,又称为套接字。实现一个Socket连接通信至少需要两个套接字,一个运行在服务端(插孔),一个运行在客户端(插头)。套接字用于描述IP地址和端口,是一个通信链的句柄。应用程序通过套接字向网络发出请求或应答网络请求。注意的是套接字既不是程序也不是协议,只是操作系统提供给通信层的一组抽象API接口。Socket通信是指应用程序利用Socket接口实现的网络通信,用于在不同的计算机之间传输数据。Socket是一种标准的API(应用程序接口),可用于在不同的计算机之间传输数据,它支持TCP、UDP等多种网络协议。在Socket通信中,客户端和服务器通过Socket接口进行通信,通信时需指定IP地址和端口号,IP地址用于唯一标志网络设备,端口主要用于区分主机上的不同应用(没有端口,操作系统没有办法区分数据到底应该发送到哪一个应用上。客户端创建一个Socket对象,并将其连接到服务器上的一个特定端口号,通过Socket对象向服务器发送数据。服务器监听指定端口号,等待客户端的连接请求,当连接请求到达时,服务器会创建一个新的Socket对象,并与客户端的Socket对象建立连接。然后,服务器和客户端之间就可以进行数据传输了。Socket通信的优点是它是跨平台的,因为Socket接口是标准的API,不受特定操作系统的限制。它也很灵活,可以使用不同的网络协议(如TCP和UDP),以满足不同的需求。Socket通信广泛应用于客户端-服务器应用程序、分布式计算、实时数据传输等领域。例如,Web服务器使用Socket通信与客户端浏览器进行通信,从而提供Web服务。9.2.1UDP类型

基于UDP协议的SocketAPI中,要分清楚DatagramSocket和DatagramPacket这两个类。Datagram意为数据包,Packet意为包裹,这两个类的关系相当于DatagramPacket是发送接收的数据包包裹,DatagramSocket是发送接收数据包包裹的快递员。表9-1(a)DatagramPacket类构造方法构造函数名称说明DatagramPacket(byte[]buf,intlength)接收构造函数,用来接收长度为length的数据包DatagramPacket(byte[]buf,intlength,InetAddressaddress,intport)发送构造函数,构造数据报包,用来将长度为

length的包发送到指定主机上的指定端口号包表9-1(b)DatagramPacket类成员方法成员方法说明InetAddressgetAddress()从接收或发送的数据报中获取对端的IP地址intgetPort()intgetPort()

从接收或发送的数据报中获取对端的端口号byte[]getData()获取数据报中的数据,数据存在字节数组中intgetLength()获取数据报中的数据的实际长度InetAddressgetAddress()从接收或发送的数据报中获取对端的IP地址DatagramPacket类表示数据报包,来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达,不保证包顺利投递。表9-2(a)DatagramSocket类构造方法表9-2(b)DatagramSocket类成员和方法DatagramSocket类表示用来发送和接收数据报包的套接字。数据报套接字是包投递服务的发送或接收点。每个在数据报套接字上发送或接收的包都是单独编址和路由的。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。在DatagramSocket总是启用UDP广播发送。为了接收广播包,应该将DatagramSocket绑定到通配符地址。在某些实现中,将DatagramSocket绑定到一个更加具体的地址时广播包也可以被接收。构造函数名称说明DatagramSocket(intport)创建一个UDPSocket对象,一般用于服务器,需要指定本机端口号(port)DatagramSocket()创建一个UDPSocket对象,一般用于客户端,不需要指定本机端口号,由操作系统随机分配构造函数名称说明void

receive(DatagramPacketp)接收数据报,如果没接收到,阻塞等待void

send(DatagramPacketp)发送数据报,不会阻塞等待void

close()关闭套接字案例9.1

通过UDP实现网络通信。(参考代码见:web模块下com.example.web.udp包中)依次运行Udpserver和Udpclient,UDP客户端发送信息“我是客户端”,UDP服务端输出的信息如图9-3(a)所示,UDP服务端发送信息“服务端在此”,UDP客户端输出的信息如图9-3(b)所示,UDP客户端和服务端实现相互通信。图9-3(a)UDP服务端输出信息图9-3(b)UDP客户端输出信息9.2.2TCP类型

基于TCP协议的SocketAPI中,ServerSocket和Socket这两个类尤为重要。其中类ServerSocket实现服务器套接字,该类遵循TCP协议,所以必须要和客户端Socket建立连接才能完成信息的接送,服务器套接字等待来自网络的请求,它基于该请求执行某些操作,请求成功则向请求者返回结果。Socket类现了客户端套接字,套接字是两台机器间通信的端点,该类同样遵循TCP协议,所以必须与ServerSocket建立连接后,才能进行信息的传送。表9-3(a)ServerSocket类成员方法表9-3(b)Socket类成员方法类名称用途Socketaccept()侦听并接收到此套接字的连接voidbind(SocketAddressendpoint,intbacklog)将ServerSocket绑定到特定地址(IP地址和端口号)InetAddressgetInetAddress()返回此服务器套接字的本地地址intgetLocalPort()返回此套接字正在侦听的端口号SocketAddressgetLocalSocketAddress()返回此套接字绑定到的端点的地址voidclose()关闭这个套接字类名称用途voidbind(SocketAddressbindpoint)将套接字绑定到本地地址InetAddressgetLocalAddress()获取绑定的套接字的本地地址InetAddressgetInetAddress()返回套接字连接的地址intgetLocalPort()返回此套接字绑定的本地端口号intgetPort()返回此套接字连接的远程端口号OutputStreamgetOutputStream()返回此套接字的输出流InputStreamgetInputStream()返回此套接字的输入流voidshutdownInput()将此套接字的输入流放在“流结束”中voidshutdownOutput()禁用此套接字的输出流voidclose()关闭此套接字表9-4基于TCP协议的Socket通信用到的其它类类名称用途InputStream、OutputStream处理字节流的抽象类,字节流的所有类的超类InputStreamReader、OutputStreamWriter处理字符流的抽象类,字节流与字符流转换的桥梁BufferedReader、BufferedWriterBufferedReader:由Reader类扩展而来,提供通用的缓冲方式文本读取,readLine读取一个文本行,从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。BufferedWriter:由Writer类扩展而来,提供通用的缓冲方式文本写入,newLine使用平台自己的行分隔符,将文本写入字符输出流,缓冲各个字符,且可以设置缓冲大小,从而提供单个字符、数组和字符串的高效写入PrintWriter提供println()方法可以写不同平台的换行符通过TCP协议的Socket服务端和客户端通信模型如图9-4所示,实现步骤如下:(1)服务端创建ServerSocket;(2)服务端通过调用accept()方法开启监听,等待接收客户端请求;客户端创建链接Socket向服务端发送请求;(3)服务端接收到来自于客户端的请求后,创建链接Socket;(4)客户端和服务端通过输入输出流实现数据交互,客户端和服务端通信结束后,调用close()方法关闭Socket与相关资源。图9-4Socket服务端和客户端通信模型(通过TCP协议)在Socket通信过程中服务端执行步骤为:(1)创建ServerSocket对象,绑定监听的端口;(2)调用accept()方法监听客户端的请求;(3)连接建立后,通过输入流读取客户端发送的请求信息;(4)通过输出流向客户端发送响应信息;(5)关闭相关资源。客户端执行步骤为:(1)创建Socket对象,指明需要链接的服务器的地址和端号;(2)链接建立后,通过输出流向服务器发送请求信息;(3)通过输入流获取服务器响应的信息;(4)关闭相关资源。案例9.2

通过TCP实现网络通信(参考代码见:web模块下com.example.web.tcp包中)依次运行TcpServer和TcpClient,TCP客户端发送信息“我是客户端”,TCP服务端输出的信息如图9-5(a)所示,TCP服务端发送信息“我是服务端”,TCP客户端输出的信息如图9-5(b)所示,TCP客户端和服务端实现相互通信。图9-5(a)TCP服务端输出的信息图9-5(b)TCP客户端输出的信息9.3HTTP通信在浏览器的地址栏里输入的网站地址叫做URL(UniformResourceLocator,统一资源定位符),每个网页也都有一个Internet地址。当我们在浏览器的地址框中输入一个URL或是单击一个超级链接时,URL就确定了要浏览的地址。浏览器通过超文本传输协议(HTTP),将Web服务器上站点的网页代码提取出来进行显示。URL的组成为:协议名://域名:端口/路径/文件名,例如:8080/zhangsan/index.html,含义如下:(1)http://:代表超文本传输协议,通知服务器显示Web页;(2)www:代表一个Web(万维网)服务器;(3):8080/:这是装有网页的服务器的域名(或站点服务器的名称)和端口;(4)zhangsan/:为该服务器上的子目录;(5)index.html:是文件夹中的一个HTML文件。9.3.1HTTP请求消息

用户在浏览器中访问URL或是单击一个超级链接时,浏览器会向服务器发送HTTP请求,浏览器发送到服务器的消息叫做HTTP请求消息(又叫HTTP请求报文),请求消息由请求行、请求头部、空行和请求体四部分组成请求行由请求方式、URL和HTTP协议版本3个部分组成。请求头部用来描述客户端的基本信息,从而把客户端相关的信息告知服务器。请求头部由多个键值对组成,常见的请求头字段如表9-5所示。最后一个请求头字段后面是一个空行,用来分割请求头部和请求体,不过一些浏览器调试工具中经过美化后这个空行没有显示出来,可以看作用一条横线代替。请求体中存放的,是要通过POST方式提交到服务器的数据,由于GET请求是从服务器获取数据,所以GET请求没有请求体。表9-5常见的请求头字段头部字段说明Host指定资源所在的服务器主机名和端口号Connection客户端与服务器之间的连接状态Content-Length请求体大小Content-Type客户端告知服务器实际发送的数据类型Accept客户端可识别的响应内容MIME类型列表Accept-Encoding客户端能进行解码的的数据解码方式Accept-Language客户端期望服务器返回那个国家语言的文档User-Agent即用户代理,指定客户端客户端使用的操作系统及版本、浏览器及版本、浏览语言等,使得服务器针对不同类型的浏览器返回不同内容9.3.2响应消息

服务器接收到请求消息后,会将处理后的数据交给客户端,及HTTP响应消息,响应消息由状态行、响应头部、空行和响应体4个部分组成。状态行位于响应消息的第一行,由HTTP协议版本、状态码、状态码的描述文本3个部分组成,客户端可根据服务器返回的响应状态码得知此次HTTP请求的结果时否成功,也可以根据状态码的类型分析除此次请求不成功的错误原因,状态码第一位数字有5种取值。表9-6状态码取值及描述信息状态码取值描述1xx信息,服务器收到请求,需要请求者继续执行操作2xx成功,请求成功被服务器接收并处理3xx重定向,需要进一步的操作以完成请求4xx客户端请求错误5xx服务器错误,服务器在处理请求的过程中发生错误响应头部用来描述服务器的基本信息,响应头部由多个键值对组成,常用的响应头字段及其描述如表9-7所示,更多的响应头字段的描述,可以查看MDN官方文档:/zh-CN/docs/Web/HTTP/Headers。响应体中存放的,是服务器响应给客户端的资源内容,可以通过浏览器调试工具中的Response面板查看服务器响应回来的内容,响应体可以包含各种类型的数据,如HTML文档、JSON数据、文件等。表9-7常用的响应头字段和说明头部字段说明Age对象在缓存代理中存贮的时长,以秒为单位Location需要将页面重新定向至的地址,为一个使用绝对路径的地址,一般在响应码为3xx的响应中才会有意义Server处理请求的源头服务器所用到的软件相关信息Accept-Ranges服务器使用HTTP响应头Accept-Ranges标识自身支持范围请求,单位值为bytes或者noneContent-Disposition在常规的HTTP应答中,Content-Disposition响应标头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。Vary描述了除方法和URL之外影响响应内容的请求头字段名。9.3.3HTTP通信

HTTP实际上是基于TCP的应用层协议,它在更高的层次封装了TCP的使用细节,使网络请求操作更为易用。TCP连接是因特网上基于流的可靠连接,它为HTTP提供了一条可靠的比特传输管道,从TCP连接一端填入的字节会从另一端以原有的顺序,正确地传递出来。表9-8HttpURLConnection类成员方法及说明方法名说明intgetResponseCode()从HTTP响应消息获取状态码voidsetRequestMethod(Stringmethod)设置发送请求的方法StringgetRequestMethod()获取发送请求的方法voidsetRequestProperty(Stringkey,Stringvalue)设置HTTP请求的请求头StringgetResponseMessage()获取服务器的响应消息(如果有)HttpURLConnection这个类位于包中,是Java的标准类,对外提供访问HTTP协议的基本功能,继承自URLConnection,可用于向网站发送GET和POST请求。案例9.3

通过HTTP实现网络通信访问豆瓣电影首页:/并返回网页源代码。(参考代码见:web模块下com.example.web.http包中)网页源代码即一个网站的原始代码,这些代码是用HTML(超文本标记语言)编写的,源代码是未编译的文本代码,可以通过浏览器或服务器翻译成网站最终显示的内容,浏览器和服务器对这些代码进行解释和渲染,从而在网页上显示我们看见的内容,那么怎么从网页源代码提取我们想要的有用信息呢?对网页源代码解析的工具这里选择Jsoup。Jsoup可从从Jsoup官网:/download下载对应的jar包,并将该文件放入项目的libs文件夹内,如下图所示。同时在项目的build.gradle文件中添加:implementation'org.jsoup:jsoup:1.17.2',“1.17.2”是jsoup的版本号,要根据实际下载的版本号对该值进行修改,然后运行build.gradle文件,使得jsoup在整个项目中可以调用。Jsoup爬虫工具使用步骤如下:(1)通过URL获得Doucment对象;(2)调用select()方法从Document实例中筛选Elements元素;(3)调用text()方法将Element(s)对象转化为String类型从而获得想要的内容表9-9Selector选择器基本语法语法示例示例说明tagnamep选择标签名为p的元素.class.showtxt选择class=’showtxt’的所有元素#id#name选择id=’name’的所有元素[attribute][target]选择带有target属性的所有元素[attr=value][target=blank]选择target="blank"的所有元素[attr^=value][src^="https"]选择src属性值以“https”开头的所有元素[attr$=value][src$=".pdf"]选择其src属性值以“.pdf”结尾的所有元素parent>childdiv>p选择父元素标签名为div的所有标签名为p的元素ancestorchilddivp选择父辈元素标签名为div的内部标签名为p的元素9.4网络编程综合案例案例9.4

通过HTTP通信访问笔趣看网页,在模拟器应用上输入小说代号和章节代号后将对应的小说章节内容显示到模拟器应用页面上。(参考代码见:web模块下com.example.web和com.example.web.novel包中)Andriod应用开发基础教程第10章高级应用10.1动画动画除了添加视觉提示,通知用户应用中的动态,还能让应用更精美,使其拥有更优质的外观和风格。Android包含不同的动画API,具体取决于动画类型。下面简单地介绍一下向界面添加动画的不同方法。10.1.1逐帧动画

在Android应用开发中,逐帧动画是一种常见的动画效果,它通过显示一系列连续的图像来创建动画效果。实现步骤如下:(1)准备逐帧动画所需的图像资源;(2)在布局文件中添加ImageView组件用于显示动画;(3)创建AnimationDrawable对象用于管理逐帧动画;(4)将帧图像资源添加到AnimationDrawable对象;(5)将AnimationDrawable对象设置为ImageView的背景;启动动画。案例10.1

演示逐帧动画.(参考代码见:FrameActivity)点击界面“start”按钮,将循环播放动画,每张图片延迟1秒播放下一张图片,点击“stop”按钮动画将停止播放。10.1.2视图动画

在Android开发中,View动画是一种常见的动画效果,View动画的作用对象是View,支持4种动画效果,分别是平移动画、缩放动画、透明度动画和旋转动画。这四种变换效果对应着Animation的四个子类:TranslateAnimation、ScaleAnimation、AlphaAnimation和RotateAnimation,这四种动画既可以通过XML来定义,也可以通过代码来动态创建。表10-1View动画4种变化说明动画名称XML标签Animation子类效果平移动画<translate>TranslateAnimation平移View缩放动画<scale>ScaleAnimation缩放View旋转动画<rotate>RotateAnimation旋转动画透明度动画<alpha>AlphaAnimation改变View透明度案例10.2

通过XML来定义View动画并进行演示(参考代码见:animation模块下anim资源目录和com.example.animation.view包中)分别点击应用界面的Alpha、Scale、Translate、Rotate和Set将会产生对应的透明度视图动画、缩放视图动画、平移视图动画和集合视图动画效果,点击“点击显示重置按钮”后,应用上方将显示重置按钮,点击重置按钮视图还原,可多次观看视图动画效果。案例10.3

通过Java定义View动画并进行演示。(参考代码见:animation模块下acom.example.animation.view包中ViewJavaActivity)相对于案例10-2,不需要在anim目录下创建XML文件,只需要通过Java代码定义动画效果即可。布局文件和案例10-2相同,Activity代码修改onClick()函数即可10.1.3

属性动画

视图动画只能对View对象添加动画效果,且只能对公开对象添加效果,比如实现对View的旋转和平移,但是不能操作背景颜色。此外,视图动画也不能修改实际的View的属性和位置,只会使绘制View的属性和位置发生变化,比如平移动画只会让View在屏幕上移动,视觉效果上发生了平移,但是View的实际位置并不会更改。属性动画几乎可以为任何对象(视图和非视图)添加视图效果,将对象属性在指定的时间内从初始值变为另一个值,改变的是对象本身。总的来说,属性动画比视图动画更加强大,具有更广泛的应用范围。表10-2属性动画相关类类名说明ValueAnimator属性动画最为核心的类,处理动画逻辑ObjectAnimator对象属性动画的操作类,使用该类能操作对象的属性动画TimeInterpolator时间插值器,计算当前属性值改变的快慢,系统预置的有线性插值器、加速减速插值器、减速插值器Property属性对象,主要定义了属性的set和get方法PropertyValuesHolder持有目标属性Property、setter和getter方法、以及关键帧集合的类KeyframeSet存储一个动画的关键帧集案例10.4属性动画演示。(参考代码见:animation模块下PropertyActivity)不同于视图动画的View,属性动画中View的属性发生了变化。10.2

多媒体表10-3MediaPlayer类常用方法方法名说明SetDataSource(Stringpath)设置音视频源getCurrentPosition()获取当前播放位置getDuration()获取载入音视频总长getVideoHeight()获取视频高度getVideoWidth获取视频宽度isPlaying()当前是否正在播放prepare()音视频播放之前,调用完成MediaPlayer同步播放准备工作prepareAsync()音视频播放之前,调用完成MediaPlayer异步播放准备工作setVolume(floatleftVolume,floatrightVolume)设置播放器音量上下限SetDisplay(SurfaceHoldersh)SetOnCompletionListener(MediaPlayer.OnCompletionListenerlistenser)显示媒体的视频部分图像设置音视频播放结束之后的监听事件SeekTo(int32position)到达音视频指定的时间位置SetOnErrorListener(MediaPlayer.OnErrorListenerlistenser)设置音视频播放错误时的监听事件SetOnPreparedListener(MediaPlayer.OnPreparedListenerlistenser)设置音视频播放错误时的监听事件SetOnSeekCompleteListener((MediaPlayer.OnSeekCompleteListenerlistenser))设置定位完成时的监听事件start()开始播放stop()停止播放pause()暂停播放reset()重置播放release()释放资源在Android应用程序中播放音视频是一项常见的需求,AndroidStudio提供了MediaPlayer类,可以很方便地实现音视频播放功能但MediaPlayer没有提供图像输出界面,需要借助SurfaceView来显示MediaPlayer播放的图像,可用SurfaceHolder的回调方法绘制SurfaceView的内容,控制图形的尺寸和大小。而Surface是Android的一个重要元素,用于Android画面的图形绘制,每一个SurfaceView都内嵌封装一个Surface。表10-4SurfaceHolder的回调方法方法名说明surfaceCreated(SurfaceHolderholder)Surface第一次创建后立即被调用surfaceChanged(SurfaceHolderholder,intformat,intwidth,intheight)Surface发生变化的时候被调用surfaceDestroyed(@NonNullSurfaceHolderholder)Surface被摧毁前被调用实现音频播放步骤如下:(1)初始化MediaPlayer;(2)设置音频文件的数据源;(3)准备和播放;(4)监听播放事件;(5)释放资源。案例10.5

实现视频资源的播放(参考代码见:media模块下)应用界面显示视频播放时长和播放进度,滑动进度条视频可从滑动进度条停止位置开始播放,单击“后退”按钮,视频倒放5s,单击“暂停”,视频停止播放,单击“开始”按钮,视频开始播放,单击“前进”按钮,视频倒放5s。10.3

AsyncTask异步任务10.3.1线程

线程(Thread)是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,多线程即一个进程中并发多个线程,每条线程并行执行不同的任务,多个线程可以更好地利用CPU的处理能力,提高程序的执行效率。当一个程序第一次启动的时候,Android会启动一个主线程即UI线程,主要负责处理用户和界面相关的事件,如按键事件、触屏事件等,并把相关的事件分发到对应的组件进行处理,如果其它相对耗时的操作阻塞UI线程,UI线程可能会失去响应,导致用户界面卡顿产生NR(ApplicationNotResponding),俗称死机,因而常将耗时操作放在新线程中。Java线程开发中常使用的方法主要有以下三种:(1)新建一个java类,使其继承Thread类,在Activity中调用该类即可;(2)匿名Thread类,使用Runnable接口;(3)实现Runnable接口,在Activity中调用。10.3.2AsyncTask及使用

新线程可能需要与主线程通信如动态更新UI组件,但是新线程不允许直接更新UI组件,为了解决这个问题,Android提供了异步任务(AsyncTask)的方式实现异步线程的操作。AsyncTask实质上是对JavaSE库中Thread的一个封装,加上了Android平台自己的特性,它是Android1.5加入的用于实现异步操作的一个类,让Android平台上异步操作更加的安全,方便和实用。由于Thread只有一个run()方法,一旦开始,无法停止,与主线程通信较为繁琐,它适合于一个非常独立的异步任务,因而独立任务时可用Thread,其他时候尽可能用AsyncTask实现异步任务。AsyncTask异步实现方法步骤如下:(1)创建AsyncTask的子类,并指定参数类型;(2)实现AsyncTask方法,AsyncTask类常见的回调方法如表10-5所示;(3)通过AsyncTask子类的实例调用execute()方法执行耗时操作,注意实例只能执行execute()方法一次,否则会抛出异常。表10-5AsyncTask类常见的回调方法方法说明voidonPreExecute()线程任务开始前执行voidonPostExecute(Booleanresult)线程任务结束时执行BooleandoInBackground(String...params)在后台执行的线程任务时自动调用voidonProgressUpdate(Integer...values)任务处理过程中进度处理,调用publishProgress()时自动调用execute(Params

params)触发异步线程任务案例10.6

使用AsyncTask实现从网络上异步下载文件并且将文件保存在外部存储中,在文件的下载过程中显示下载进度。(参考代码见:asynctask模块下)10.4

Handler10.4.1Handler概念和相关机制

Handler是一套Android消息传递机制,主要用于线程间通信,Handler运行在主线程中,子线程中需更新UI的操作信息可以通过Message对象传递到UI主线程,从而实现子线程对UI的更新处理,最终实现对异步消息的处理,保证线程安全。可以看出Handle主要具备两个功能,一个是更新UI,另一个就是发送消息和对消息进行处理。Handle消息传递机制流程主要包括4个步骤:异步通信准备、消息发送、消息循环和消息处理Handler发送一个消息后,会将此消息加入消息队列中,循环器遍历消息队列并且将队列中的消息分发给对应的Handler进行处理,这就完成了一个消息的发送和处理过程。表10-6Handle消息传递机制各自角色和作用概念作用UI线程处理与UI相关的更新、操作等事件子线程人为开启的线程,处理耗时操作消息线程间通讯的数据单元,存储需操作的通信消息消息队列存储Handler发送过来的消息(Message)Handler添加消息到消息队列;处理循环器分派过来的消息Looper消息循环:循环取出消息队列的消息和将取出的消息发送给对应的Handler处理表10-7Handle机制中的核心类类名称重要方法作用处理器类HandlersendMessage(Messagemsg)将消息发送到队列中post(Runnabler)dispatchMessage(Messagemsg)将消息发送给对应的HandlerhandleMessage(Messagemsg)对消息进行相关处理消息队列类MessageenqueueMessage(Messagemsg,longwhen)入队:将消息插入到消息队列中Messagenext()出列:从消息队列中移出消息循环器类Looperprepare()初始化循环器,创建消息队列loop()消息循环Handler使用步骤分为四步:(1)新建Handler对象,覆写handleMessage(Messagemsg)方法;(2)新建Message对象,设置其携带的数据;(3)在子线程中通过Handler.sendMessage(Messagemsg)等方法发送信息;在Handler的handleMessage(Messagemsg)方法中处理消息,通知主线程作出相对应的UI工作。Message类是一个包含任意类型的描述数据对象,此对象可以发送给Handler。对象包含两个额外的int字段和一个额外的对象字段,这样可以使得在很多情况下不用做分配工作。尽管Message的构造器是公开的,但是获取Message对象的最好方法是调用Message.obtain()或者Handler.obtainMessage(),这样是从一个可回收对象池中获取Message对象。表10-8Message类字段及含义字段含义what用户自定义的消息代码,这样接收者可以识别这个消息的信息来源。每个Handler包含自己的消息代码,所以不用担心自定义的消息跟其他Handlers有冲突。arg1定义传递的int类型的值1arg2定义传递的int类型的值2obj定义传递的值类型是object(对象),可以传递各种类型的值10.4.2Handler应用

案例10.7

通过Handler实现倒计时操作。(参考代码见:handle模块下)用户可以选择倒计时结束的日期和时间,点击“点击进入倒计时”按钮,如果倒计时日期和时间比当前时间早,不会进入倒计时操作,当倒计时日期和时间比当前时间晚,倒计时开始。10.5

Fragment10.5.1Fragment概述

Fragment是Android3.0引入的新API,它可以看作是Activity中的子页面,能单独进行管理和维护,一个Fragment可以被多个Activity或者其他Fragment使用,也可以嵌套其他的Fragment,提高应用程序的代码可重用性和灵活性,Fragment也可以在运行时动态地添加、移除、替换等UI元素,提供更加灵活的响应式用户界面,但它不能单独使用必须被“嵌入”到Activity中。Fragment可以灵活地适应不同的屏幕尺寸和设备类型,使得应用程序在各种设备上都能够自适应,下图展示了Fragment分别对应手机与平板间不同情况的处理。平板屏幕尺寸较大一个Activity同时包含两个Fragment,即左侧的FragmentA导航栏和右侧的FragmentB内容列表,选择Activity中的FragmentA导航栏项能跳转到同一个Activity中的FragmentB内容列表,手机由于屏幕尺寸较小一个Activity只包含一个Fragment,选择一个Activity中的FragmentA导航栏项会跳转到另一个Activity中的FragmentB内容列表。10.5.2Fragment生命周期

Fragment拥有自己的生命周期,但是还是会受到Activity的生命周期的影响,只有Activity处于运行状态才可以对Fragment操作,也就是说Activity销毁时,Activity中所有的Fragment都会销毁。表10-9Fragment生命周期方法生命周期含义onAttach()Fragment被添加到Activity时被回调onCreate()创建Fragment时被回调onCreateView()每次创建、绘制该Fragment的View组件时回调该方法onActivityCreated()Fragment所在的Activity被启动完成后回调该方法onStart()启动Fragment时被回调onResume()恢复Fragment时被回调,Fragment能与用户交互onPause()暂停Fragment时被回调,Fragment不再与用户交互onStop()停止Fragment时被回调,Fragment不可见时回调onDestroyView()销毁与Fragment有关的视图,但未与Activity解除绑定onDestroy()销毁Fragment时被回调onDetach()Fragment与Activity关联被取消时调用10

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论