第8章 Service解析.

Slides:



Advertisements
Similar presentations
Java 程序分类 Java Application :是完整程序,需要独立的解 释器解释运行;以 “.java” 为后缀的文件,以 main() 方法作为程序入口,由 java 编译器编译生 成字节码,由 Java 解释器加载执行字节码。 Java Applet 没有 main() 方法作为程序入口,是嵌在.
Advertisements

第四章 类、对象和接口.
3.2 Java的类 Java 类库的概念 语言规则——程序的书写规范 Java语言 类库——已有的有特定功能的Java程序模块
JAVA 编 程 技 术 主编 贾振华 2010年1月.
项目6 通用堆栈.
授课教师:江星玲 1.
第13章 繪圖與多媒體 13-1 顯示圖檔-行動相簿 13-2 音樂播放-音樂播放器 13-3 影片播放-視訊播放器
Hello小程序的运行和编译 Java AppletJava小程序的构成 1、关键字
實驗五:多媒體播放器選單介面.
位置與地圖應用 此投影片為講解Android如何取得定位經緯度和使用Google Map地圖.
第二章 JAVA语言基础.
创意源自激情,技术成就梦想 畅翼创新俱乐部 2012年春俱乐部第三次技术培训 赵程.
Activity之间的数据传递.
ArrayAdapter & Spinner
使用Android Studio 開發Android App 靜宜大學資管系 楊子青
厦门大学数据库实验室 报告人:谢荣东 导师:林子雨 2014年8月30日
APP課程:Android程式設計開發環境與工具介紹
第5章 Android服务(Service)
Design Pattern (2) 设计模式(2) Institute of Computer Software 2018/9/21
第2章 建立Android應用程式 2-1 Java語言、XML文件與Android 2-2 建立第一個Android應用程式
Android + JUnit 單元測試 建國科技大學資管系 饒瑞佶 2012/8/19V4.
2.1 基本資料型別 2.2 變數 2.3 運算式與運算子 2.4 輸出與輸入資料 2.5 資料型別轉換 2.6 實例
實驗十三:顯示目前經緯度位置.
API设计实例分析 通用IO API.
使用Android控制Arduino 史先强
第11章 Android GPS位置服务与地图编程
Java语言程序设计 第七部分 多线程.
第一个Android程序 本讲大纲: 1、创建Android应用程序 2、Android项目结构说明 3、运行Android应用程序
第8章 Android内容提供者(ContentProvider)应用
崑山科技大學資訊管理系 伺服網頁程式設計 系統開發細部流程 教師:游峰碩.
Ch5 Android應用程式的主要組成.
Chapter 7 Android應用元件 Android應用元件可以幫助我們獲得系統資源訊息(ActivityManager)、提供系統服務(Service)、搜尋系統服務(SearchManager)、監聽Intent訊息(Broadcast Receiver)以及資料共享(ContentProvider和ContentResolver)。
西南科技大学网络教育系列课程 高级语程序设计(Java) 第五章 继承、接口与范型.
厦门大学数据库实验室 MapReduce 连接
第4章 Android生命周期.
ContentProvider與資料共享
第9章 使用意圖啟動活動與內建應用程式 9-1 意圖的基礎 9-2 使用意圖啟動活動
ANDROID PROGRAMMING2.
程式設計實作.
CH09 套件 物件導向程式設計(II).
软件建模精要 面向对象软件建模技术.
Android + Service 建國科技大學 資管系 饒瑞佶.
2018/12/3 面向对象与多线程综合实验-网络编程 教师:段鹏飞.
第9章 類別圖與物件圖 9-1 類別圖與物件圖的基礎 9-2 類別圖的符號 9-3 類別關係 9-4 物件圖 9-5 繪製類別圖與物件圖
第2讲 移动应用开发基础知识(二) 宋婕
Java语言程序设计 第八部分 Applet小程序.
建立Android新專案 Android智慧型手機程式設計 程式設計與應用班 建國科技大學 資管系 饒瑞佶 2012/4 V1
中国矿大计算机学院杨东平 第5章 接口和包 中国矿大计算机学院杨东平
Android 视频教程简介.
Java程序设计 第2章 基本数据类型及操作.
C/C++/Java 哪些值不是头等程序对象
第10章 GPS位置服务与地图编程.
主编:钟元生 赵圣鲁.
Intent.
Android 开发入门.
Android Application Component
JAVA 编 程 技 术 主编 贾振华 2010年1月.
《JAVA程序设计》 语音答疑 辅导老师:高旻.
實驗九:延續實驗八, 製作一個完整音樂播放器
Location Based Services - LBS
Java程式初體驗大綱 大綱 在學程式之前及本書常用名詞解釋 Hello Java!程式 在Dos下編譯、執行程式
Interfaces and Packages
第二章 Java语法基础.
第二章 Java基本语法 讲师:复凡.
Android藍芽聊天室 SDK內的範例程式
第2章 Java语言基础.
第9章 BroadcastReceiver的使用
Android进程间通讯.
第二章 Java基础语法 北京传智播客教育
Part 8 Broadcast Receiver、Service和App Widget
Presentation transcript:

第8章 Service解析

本章知识结构图

本章示例

Service简介 什么是Service? A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background. Service与Activity类似,都是Android中四大组件之一,并且二者都是从Context派生而来,最大的区别在于Service没有实际的界面,而是一直在Android系统的后台运行,相当于是一个没有图形界面的Activity程序,它不能自己直接运行,需要借助Activity或其他Context对象启动。

Service的创建及常用方法 与开发其它Android组件类似,开发Service组件需从系统中的Service继承。系统中Service类包含的方法主要有: abstract IBinder onBind(Intent intent):该方法是一个抽象方法,所有Service子类必须实现该方法。该方法将返回一个IBinder对象,应用程序可通过该对象与Service组件通信; void onCreate():当Service第一次被创建时,将立即回调该方法; void onDestroy():当Service被关闭之前,将回调该方法; void onStartCommand(Intent intent,int flags,int startId):每次客户端调用startService(Intent intent)方法启动该Service时都会回调该方法; boolean onUnbind(Intent intent):当该Service上绑定的所有客户端都断开连接时将会回调该方法。

配置Service 定义Service子类时必须实现onBind()方法,然后还需在AndroidManifest.xml文件中进行配置,配置时可通过<intent-filter…/>元素指定它可被哪些Intent启动。 <service android:name=“.MyService”> <intent-filter> <action android:name=“iet.jxufe.cn.android.MyService”/> </intent-filter> </service> Action中的值一定要与程序中创建的Intent的Action的值一致,程序就是根据Action的值来查找相应的Service从而启动它。

运行Service的两种方式 通过Context的startService()启动Service后,访问者与Service之间没有关联,该Service将一直在后台执行,即使调用startService()的进程结束了,Service仍然还存在,直到有进程调用stopService(),或者Service自己自杀(stopSelf())。这种情况下,Service与访问者之间无法进行通信、数据交换。往往用于执行单一操作,并且没有返回结果。 通过Context的bindService()绑定Service后,Service就和调用bindService()的组件同生共死了,也就是说当调用bindService()的组件销毁了,那么它绑定的Service也要跟着被结束。当然期间也可以调用unbindservice()让Service提前结束。

运行Service的两种方式 以上两种方式也可以混合使用,即一个Service既可以启动也可以绑定,只需要同时实现onStartedCommand()(用于启动)和onBind()(用于绑定)方法,那么只有调用stopService(),并且调用unbindservice()方法后,该Service才会被销毁。 注意:服务运行在它所在进程的主线程,服务并没有创建它自己的线程,也没有运行在一个独立的进程上。如果服务中需做一些消耗CPU或者阻塞的操作,应该在服务中创建一个新的线程去处理。通过使用独立的线程,将会降低程序出现ANR(Application No Response程序没有响应)的风险,程序的主线程仍然可以保持与用户的交互。

绑定Service过程 Context的bindService()方法的完整方法签名为:bindService(Intent service,ServiceConnection conn, int flags),该方法的三个参数含义如下: service:该参数表示与服务类相关联的Intent对象,用于指定所绑定的Service; conn:该参数是一个ServiceConnection对象,该对象用于监听访问者与Service之间的连接。当访问者与Service间连接成功时,将回调该ServiceConnection对象的onServiceConnected (ComponentName name,IBinder service)方法; flags:指定绑定时是否自动创建Service(如果Service还未创建)。该参数可指定BIND_AUTO_CREATE(自动创建)。

绑定Service 当开发Service类时,必须提供一个onBind()方法,在绑定本地Service的情况下,onBind()方法所返回的IBinder对象将会传给ServiceConnection对象里onServiceConnected(ComponentName name,IBinder service)方法的service参数,这样访问者就可以通过IBinder对象与Service进行通信。 实际开发时通常会采用继承Binder(IBinder的实现类)的方式实现自己的IBinder对象。

案例 1、通过startService()启动服务、stopService()停止服务 2、通过bindService()绑定服务、unbindService()解除绑定 3、两种方式混合使用 4、获取服务数据

Service详解 问题与讨论 两种方式混合使用时,方法的执行顺序是怎么样的? 1、先启动后绑定 2、先绑定后启动

案例总结 1)先启动Service,然后绑定Service。测试步骤:【启动Service】→【绑定Service】→【启动Service】→【停止Service】→【绑定Service】→【解绑Service】。 总结:调用顺序如下:onCreate()→[onStartCommand()1到N次] →onBind()→ onServiceConnected()→onUnbind()[→ onServiceConnected()→onRebind()0到N次]→onDestroy()。

案例总结 2)先绑定Service,后启动Service。测试步骤:【绑定Service】→【启动Service】→【绑定Service】→【解绑Service】→【启动Service】→【停止Service】。 总结:调用顺序如下:onCreate()→onBind()→onServiceConnected() →[onStartCommand() 1到N次]→onUnBind[→onServiceConnected() →onRebind()0到N次→onUnBind]→onDestroy()。

案例总结 注意: (1)未启动Service而直接停止Service不起作用,但未绑定Service而先解绑Service则程序出错,强制退出; (2)若该Service处于绑定状态下,该Service不会被停止即单击停止按钮不起作用,当单击解绑Service按钮时,它会先解除绑定随后直接销毁; (3)若在解除之前,没有单击停止Service,则只解绑而不会销毁。

Service的生命周期 每当Service被创建时会回调onCreate()方法,每次Service被启动时都会回调onStartCommand()方法,多次启动一个已有的Service组件将不会再回调onCreate()方法,但会回调onStartCommand()方法。 绑定服务的执行过程: 执行单击事件方法根据Intent找到相应的Service类,并初始化该类调用Service的onCreate()方法调用该类的onBind()方法调用onServiceConnected()方法。 多次单击绑定服务按钮,并不会重复执行绑定方法。一旦解绑,调用onUnbind()方法,然后自动销毁。

跨进程调用Service AIDL:Android Interface Definition Language AIDL是一种接口定义语言,用于约束两个进程间通信规则,供编译器生成代码,实现Android设备上的两个进程间通信(IPC)。 进程之间的通信信息,首先会被转换成AIDL协议消息,然后发送给对方,对方收到AIDL协议消息后再转换成相应的对象。 由于进程之间的通信信息需要双向转换,所以android采用代理类在背后实现了信息的双向转换,代理类由android编译器生成,对开发人员来说是透明的。

跨进程调用Service 客户端访问Service时,Android并不是直接返回Service对象给客 户端,Service只是将一个回调对象(IBinder对象)通过onBind()方法 回调给客户端。 与绑定本地Service不同的是,远程Service的onBind()方法只是将 IBinder对象的代理传给客户端的ServiceConnection的 onServiceConnected()的第二个参数。 当客户端获取了远程的Service的IBinder对象的代理之后,接下来可 通过该IBinder对象去回调远程Service的属性或方法。

建立AIDL文件 AIDL定义接口的源代码必须以.aidl结尾,接口名和aidl文件名相同; AIDL接口中用到数据类型,除了基本类型、String、List、Map、CharSequence之外,其他类型全部都需要导包,即使它们在同一个包中也需要导包。 定义好AIDL接口之后(如Song.aidl),Android Studio集成开发工具会自动生成aidl文件夹,同时会在在build文件夹下生成相应的包,并生成一个Song.java接口,在该接口里包含一个Stub内部类,该内部类实现了IBinder、Song两个接口,这个Stub类将会作为远程Service的回调类。由于它实现了IBinder接口,因此可作为Service的onBind()方法的返回值。如果没有生成,可选择菜单栏中的buildClean Project 清理项目

客户端访问AIDLService 开发客户端的第一步就是将Service端的AIDL接口文件复制到客户端应用中。注意:复制时可切换到project视图下,然后把整个aidl文件夹复制过来 客户端绑定远程Service与绑定本地Service的区别不大,只需要三步: 创建一个ServiceConnection对象,需要实现ServiceConnection接口的两个方法; 将传给onServiceConnected()方法的IBinder对象的代理类转换成IBinder对象,从而利用IBinder对象调用Service中的相应方法; 将创建好的ServiceConnection对象作为参数,传给Context的bindService()方法绑定远程Service。

案例 设计并实现下图所示功能效果。单击按钮可获取远程Service中的数据,并显示在文本框中。

案例 假设A应用需要与B应用进行通信,调用B应用中的getName()、getAuthor()方法,B应用以Service方式向A应用提供服务。(我们可以把A应用看成是客户端,B应用看成是服务端,分别命名为AIDLClient 、AIDLServer)。整个过程需要以下几步: 1、在Server端编写AIDL文件 package cn.jxufe.iet.aidlserver;; interface Song{ String getName(); String getAuthor(); }

案例 编写Aidl文件时,需要注意: 1.接口名和aidl文件名相同; 2.接口和方法前不用加访问权限修饰符public,private等,也不能用final,static; 3.Aidl默认支持的类型包话java基本类型(int、long、boolean等)和(String、List、Map、CharSequence),使用这些类型时不需要import声明。对于List和Map中的元素类型必须是Aidl支持的类型。如果使用自定义类型作为参数或返回值,自定义类型必须实现Parcelable接口。 4.自定义类型和AIDL生成的其它接口类型在aidl描述文件中,应该显式import,即便在该类和定义的包在同一个包中。 5.在aidl文件中所有非Java基本类型参数必须加上in、out、inout标记,以指明参数是输入参数、输出参数还是输入输出参数。 6.Java原始类型默认的标记为in,不能为其它标记。

案例 当完成aidl文件创建后,Android Studio集成开发工具会自动生成aidl文件夹,同时会在在build文件夹下生成相应的包,并生成一个Song.java接口。接口文件中生成一个Stub抽象类,里面包括aidl定义的方法,还包括一些其它辅助性的方法。 对于远程服务调用,远程服务返回给客户端的对象为代理对象,客户端在onServiceConnected(ComponentName name, IBinder service)方法引用该对象时不能直接强转成接口类型的实例,而应该使用asInterface(IBinder iBinder)进行类型转换。

案例 2、在ADILServer应用中实现aidl文件生成的接口(本例是Song),但并非直接实现接口,而是通过继承接口的Stub来实现(Stub抽象类内部实现了aidl接口),并且实现接口中的方法。 public class SongBinder extends Stub{ public String getName() throws RemoteException { return name; } public String getAuthor() throws RemoteException { return author; 3、把AIDLService应用中aidl文件复制到客户端应用中,。接下来即可在AIDLClient应用中实现与AIDLService应用通信。

调用系统服务 在Android系统中提供了很多内置服务类,通过它们提供的系列方法,可以获取系统相关信息。 发送短信需要调用系统的短信服务,主要用到SmsManager管理类,该类可以实现短信的管理功能,通过sendXxxMessage()方法进行短信的发送操作,例如sendTextMessage()方法用于发送文本信息 PendingIntent是对Intent的包装,一般通过调用Pendingintent的getActivity()、getService() 等静态方法来获取PendingIntent对象。与Intent对象不同的是:PendingIntent通常会传给其他应用组件,从而由其他应用程序来执行PendingIntent所包装的“Intent”。

案例 设计实现下图所示功能效果。界面中包含两个文本输入框和一个按钮,文本输入框分别输入收件人的号码以及要发送的信息。单击“发送”按钮即可发送短信。 提示:由于短信涉及到用户隐私,需要用户授权,对应的权限为:android.permission.SEND_SMS。

测试题 1.运行服务的两种方式是___________________和________________。 2.简述运行服务的两种方式的区别。 3.简述绑定服务执行的过程。 4.下列不属于Service生命周期的回调方法是 ( )。 A) onCreate() B) onBind() C) onStart() D) onStop() 5.在创建Service子类时,必须重写父类的以下哪个方法( )。 A) onCreate() B) onBind() C)onStartCommand() D)onDestroy() 6.ServiceConnection中onServiceConnected() 触发条件描述正确的是( )。 A) bindService()方法执行成功后。 B) bindService()方法执行成功同时onBind()方法返回非空IBinder对象。 C) Service的onCreate()方法和onBind()方法执行成功后。 D) Service的onCreate()和onStartCommand()方法启动成功后。