01_Service

Save this PDF as:
 WORD  PNG  TXT  JPG

Size: px
Start display at page:

Download "01_Service"

Transcription

1 移动平台应用软件开发 Service 主讲 : 张齐勋 移动平台应用软件开发 课程建设小组 北京大学 二零一七年

2 什么是 Service 与 Activity 一样, 同属 Android 基本组件 后台运行, 不与用户交互, 没有可视化界面 最常见的 Service 如 : 在后台播放歌曲 后台执行文件的下载 同样需在 AndroidManifest.xml 中注册 每一个服务均继承自父类 Service Service 可以通过 Context.startService() 或 Context.bindService() 来创建

3 void oncreate( ) Service 生命周期 void onstartcommand( ) void ondestroy()

4 实现 Service 实现 Service 需要继承 android.app.service 类, 然后重写 onstartcommand onbind 和 oncreate 等方法 如果在 Activity 等组件中通过 Context.startService() 方法启动 Service, 需要重写 onstartcommand 方法 如果在 Activity 等组件中通过 Context.bindService() 方法绑定 Service, 需要重写 onbind 方法

5 Service 的调用 如果调用 Context.startService(), 那么系统将会查找这个 Service, 如果必要则创建它并调用它的 oncreate() 方法, 然后调用 onstartcommand 方法, Service 开始运行直到 Context.stopService() 或者 stopself() 方法被调用 注意, 多次调用 Context.startservice() 不会嵌套 ( 即使会有相应的 onstartcommand 被调用 ), 所以无论同一个服务被启动了多少次, 一旦调用 Context.stopService() 或者 stopself(), 他都会被停止 一个服务只会创建一次, 销毁一次, 但可以开始多次, 因此,onCreate 和 ondestroy 方法只会被调用一次, 而 onstartcommand 方法会被调用多次

6 Service 示例 public class MyService extends Service public IBinder onbind(intent intent) { Log.d("Myservice","Myservice->onBind"); return null; public void oncreate() { super.oncreate(); Log.d("Myservice","Myservice->onCreate"); public int onstartcommand(intent intent, int flags, int startid) { Log.d("Myservice","Myservice->onStartCommand"); return super.onstartcommand(intent, flags, startid); startservice(new Intent(this,MyService.class)); startservice(new Intent(this,MyService.class)); startservice(new Intent(this,MyService.class)); stopservice(new Intent(this,MyService.class)); stopservice(new Intent(this,MyService.class)); public void ondestroy() { super.ondestroy(); Log.d("Myservice","Myservice->onDestroy");

7 扩展练习 重写 onstartcommand oncreate 方法 ondestroy, 并通过 Log 打印信息, 分析这几个函数的调用时机 在 onstartcommand 中开启一个新的线程, 每隔一秒输出一条信息

8 在 Service 异步执行任务 Android 提一个工具类 AsyncTask 实现 AsyncTask 类中定义的下面一个或几个方法 Ø onpreexecute() 开始执行前的准备工作 ; Ø doinbackground(params...) 开始执行后台处理, 可以调用 publishprogress 方法来更新实时的任务进度 ; Ø onprogressupdate(progress...) 在 publishprogress 方法被调用后,UI thread 将调用这个方法从而在界面上展示任务的进展情况, 例如通过一个进度条进行展示 Ø onpostexecute(result) 执行完成后的操作, 传送结果给 UI 线程

9 AsyncTask Android 另外提供了一个工具类 :AsyncTask 使得 UI thread 的使用变得异常简单 它使创建需要与用户界面交互的长时间运行的任务变得更简单, 不需要借助线程和 Handler 即可实现 使用 AsyncTask 时, 需要继承 AsyncTask 父类并重写其中的回调函数和后台处理函数

10 AsyncTask 使用 实现 AsyncTask 类中定义的下面一个或几个方法 Ø onpreexecute() 开始执行前的准备工作 ; Ø doinbackground(params...) 开始执行后台处理, 可以调用 publishprogress 方法来更新实时的任务进度 ; Ø onprogressupdate(progress...) 在 publishprogress 方法被调用后,UI thread 将调用这个方法从而在界面上展示任务的进展情况, 例如通过一个进度条进行展示 Ø onpostexecute(result) 执行完成后的操作, 传送结果给 UI 线程 这 4 个方法都不能手动调用 所以要求 : 1) AsyncTask 的实例必须在 UI thread 中创建 ; 2) AsyncTask.execute 方法必须在 UI thread 中调用 ;

11 示例 : 使用 AsyncTask 的计时器 private Button BtnStart; private TextView txtviewtimer; private int Count = 0; private boolean isrunning = false; BtnStart = (Button) findviewbyid(r.id.btnstart); txtviewtimer = (TextView) findviewbyid(r.id.txtviewtimer); BtnStart.setOnClickListener(btnlistener); private Button.OnClickListener btnlistener = new Button.OnClickListener() { public void onclick(view v) { // TODO Auto-generated method stub isrunning=true; TimeTickLoad timetick = new TimeTickLoad(); timetick.execute(); ;

12 private class TimeTickLoad extends AsyncTask<Void, Integer, Void> { protected void onpreexecute() { super.onpreexecute(); protected Void doinbackground(void... arg0) { while (isrunning) { try { Thread.sleep(1000); catch (InterruptedException e) { // TODO Auto-generated catch block e.printstacktrace(); Count++; publishprogress(null); return null;

13 protected void onprogressupdate(integer... values) { // TODO Auto-generated method stub txtviewtimer.settext(" 时间已经过去了 " + String.valueOf(Count) + "S"); super.onprogressupdate(values); protected void onpostexecute(void result) { super.onpostexecute(result);

14 讨论 在天气预报项目中, 如何利用服务的机制?

15 Q&A 本讲结束!