一、Started服务与Bound服务的最重要的区别:
1、Bound服务:要依赖底层(也就是Linux的通讯机制)
2、Bound服务:有客户端和服务器的概念
3、Bound服务:只要有一个绑定者存在,那么服务继续运行,只有在所有绑定者都退出,服务才停止
<service android:enabled=“true” android:name=“.PlayService”/>
服务按启动方式分为两类
Started:适用于 Activity 与服务之间没有调用交互的情况 用startService()来启动(每调用一次这个方法,就会启动一个服务进程) 一旦启动,就运行在后台,即使启动它的对象都销毁了 通常只启动,不返回值 通常执行完服务的操作后,服务自动停止 onStartCommand()方法,服务的业务逻辑就写在这里
Bound:适用于 Activity 与服务之间需要传递参数或方法调用的情况 bindService()来绑定 提供客户端服务器接口来启动 发送请示,得到返回值,甚至通过IPC(Linux操作系统中,进程之间通讯的机制)来通讯 只要有一个绑定者存在,那么服务继续运行,只有在所有绑定者都退出,服务才停止 onBind()方法 ,服务的业务逻辑就写在这里
Started启动服务的Activity
Started方法的实现步骤:
继承 Service 类,实现自己的服务
在 AndroidManifest 中注册服务
用 startService 方法启动服务
服务的业务逻辑的代码编写:startCommand 方法中
停止服务:用 stopService、stopSelf 方法
1 System.out.println("启动非阻塞的服务"); 2 intentNotBlock = new Intent(Service_Demo2Activity.this, NotBlockService.class); 3 //启动非阻塞的服务 4 ComponentName notBlockCpnName = startService(intentNotBlock); 5 6 7 System.out.println("停止非阻塞的服务"); 8 //停止非阻塞的服务,若停止成功,则返回true,否则,返回false 9 boolean bl = stopService(intentNotBlock);
服务类
public class NotBlockService extends Service { private Thread t; /** * 函数名称 :onBind * 功能描述 : * 参数说明 : * @param intent * @return * 返回值: * * 修改记录: * 日期 :2012-1-11 下午5:30:21 修改人:gy * 描述 : * */ @Override public IBinder onBind(Intent intent) { System.out.println("NotBlockService unbindService"); return null; } /** * 函数名称 :onCreate * 功能描述 : * 参数说明 : * 返回值: * * 修改记录: * 日期 :2012-1-11 下午5:30:51 修改人:gy * 描述 : * */ @Override public void onCreate() { super.onCreate(); System.out.println("NotBlockService onCreate"); } /** * 函数名称 :onStartCommand * 功能描述 : * 参数说明 : * @param intent * @param flags * @param startId * @return * 返回值: * * 修改记录: * 日期 :2012-1-11 下午5:30:38 修改人:gy * 描述 : * */ @Override public int onStartCommand(Intent intent, int flags, int startId) { int iRet = super.onStartCommand(intent, flags, startId); //非阻塞:用子线程来解决 t = new Thread(new Runnable() { @Override public void run() { for(int i = 0; i < 100; i++) { System.out.println("NotBlockService onStartCommand 当前的 i :" + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); //当线程调用 interrupt 方法后,跳出循环 break; } } }); t.start(); return iRet; } /** * 函数名称 :onDestroy * 功能描述 : * 参数说明 : * 返回值: * * 修改记录: * 日期 :2012-1-11 下午5:30:57 修改人:gy * 描述 : * */ @Override public void onDestroy() { super.onDestroy(); if(t != null && t.isAlive()) { //中断线程 t.interrupt(); } System.out.println("NotBlockService onDestroy"); } }
-------------------------------------------------------------------------------------------------------------------------------------------------
Bound方法的实现步骤:
继承 Service 或 IntentService 类,实现自己的服务
在 Service 类中定义一个内部类,这个类实现 IBinder 接口,提供一个返回当前 Service 对象的方法
在 AndroidManifest 中注册服务
在 Activity 中用 bindService 方法来绑定服务,并且在 Activity 类中定义一个内部类,这个类实现 ServiceConnection 接口,用于返回绑定对象,并获取绑定的服务,通过获取到的服务对象调用相应的方法
在 Activity 中用 unBindService 方法取消绑定服务
启动的类
1 //绑定服务 2 Intent intent = new Intent(Service_Demo3Activity.this, BinderService.class); 3 //绑定到 BinderService 服务 4 /** 5 * bindService方法参数: 6 * 第一个参数:intent 7 * 第二个参数:ServiceConnection(连接到服务器上的服务的连接对象) 8 * 第三个参数:int 9 */ 10 boolean bl = bindService(intent, svcConn, Context.BIND_AUTO_CREATE); 11 System.out.println("Service_Demo3Activity bindService 执行后 bl:" + bl); 12 13 14 15 16 //停止服务 17 if (svcConn != null) 18 { 19 //解除绑定 BinderService 服务 20 unbindService(svcConn); 21 System.out.println("Service_Demo3Activity unbindService 执行后"); 22 } 23 24 25 26 27 //服务连接对象:定义服务绑定的回调,传递给绑定服务 28 private ServiceConnection svcConn = new ServiceConnection() 29 { 30 /** 31 * 32 * 函数名称 :onServiceConnected 33 * 功能描述 : 服务连接上的时候,这个方法被调用 34 * 参数说明 : 35 * @param name 36 * @param service 从服务器返回的 Binder 对象 37 * 返回值: 38 * 39 * 修改记录: 40 * 日期 :2012-1-12 下午3:45:03 修改人:gy 41 * 描述 : 42 * 43 */ 44 @Override 45 public void onServiceConnected(ComponentName name, IBinder service) 46 { 47 System.out.println("1 Service_Demo3Activity onServiceConnected name:" + name.toString()); 48 //获取绑定对象 49 MyBinder binder = (MyBinder) service; 50 System.out.println("2 Service_Demo3Activity onServiceConnected"); 51 //获取 BinderService 对象 52 BinderService bs = binder.getService(); 53 System.out.println("3 Service_Demo3Activity onServiceConnected bs=" + bs); 54 //调用服务端的方法,这个方法是在服务端执行 55 bs.printMsg(); 56 System.out.println("4 Service_Demo3Activity onServiceConnected"); 57 } 58 59 /** 60 * 61 * 函数名称 :onServiceDisconnected 62 * 功能描述 :服务断开的时候,这个方法被调用 63 * 参数说明 : 64 * @param name 65 * 返回值: 66 * 67 * 修改记录: 68 * 日期 :2012-1-12 下午3:45:24 修改人:gy 69 * 描述 : 70 * 71 */ 72 @Override 73 public void onServiceDisconnected(ComponentName name) 74 { 75 System.out.println("Service_Demo3Activity onServiceDisconnected"); 76 } 77 };
服务类
1 public class BinderService extends Service 2 { 3 //提供给客户端的绑定对象 4 private IBinder myBinder = new MyBinder(); 5 private boolean isRun = true; 6 private Thread t; 7 8 /** 9 * ********************************************************** 10 * 内容摘要 :被用于客户端绑定者的类<p> 11 * 这里的服务,通过绑定者实现,提供给客户端访问在服务器中的方法 12 * 13 * 作者 :kyx 14 * 创建时间 :2012-1-12 下午4:07:38 15 * 当前版本号:v1.0 16 * 历史记录 : 17 * 日期 : 2012-1-12 下午4:07:38 修改人: 18 * 描述 : 19 *********************************************************** 20 */ 21 public class MyBinder extends Binder 22 { 23 /** 24 * 25 * 函数名称 : getService 26 * 功能描述 : 为客户端取回当前的 BinderService 实例 27 * 参数及返回值说明: 28 * @return 29 * 30 * 修改记录: 31 * 日期 :2012-1-12 下午9:12:34 修改人:gy 32 * 描述 : 33 * 34 */ 35 public BinderService getService() 36 { 37 //返回 BinderService 的实例,使客户端可以访问到在服务器上的公有方法 38 System.out.println("BinderService getService() BinderService.this=" + BinderService.this); 39 return BinderService.this; 40 } 41 } 42 43 44 @Override 45 public void onCreate() 46 { 47 super.onCreate(); 48 System.out.println("BinderService onCreate"); 49 } 50 51 /** 52 * 函数名称 :onBind 53 * 功能描述 : 绑定 54 * 参数说明 : 55 * @param intent 56 * @return 57 * 返回值: 58 * 59 * 修改记录: 60 * 日期 :2012-1-11 下午3:53:11 修改人:gy 61 * 描述 : 62 * 63 */ 64 @Override 65 public IBinder onBind(Intent intent) 66 { 67 System.out.println("BinderService onBind"); 68 return myBinder; 69 } 70 71 /** 72 * 73 * 函数名称 : printMsg 74 * 功能描述 : 打印信息 75 * 参数及返回值说明: 76 * 77 * 修改记录: 78 * 日期 :2012-1-12 下午9:04:33 修改人:gy 79 * 描述 : 80 * 81 */ 82 public void printMsg() 83 { 84 t = new Thread() 85 { 86 /** 87 * 函数名称 :run 88 * 功能描述 : 89 * 参数说明 : 90 * 返回值: 91 * 92 * 修改记录: 93 * 日期 :2012-2-8 下午4:27:26 修改人:gy 94 * 描述 : 95 * 96 */ 97 @Override 98 public void run() 99 { 100 super.run(); 101 int i = 1; 102 while(isRun) 103 { 104 System.out.println("BinderService printMsg i:" + i++); 105 //判断是否调用了中断线程方法 106 if(this.isInterrupted()) 107 { 108 isRun = false; 109 break; 110 } 111 } 112 System.out.println("=======线程结束======="); 113 } 114 }; 115 t.start(); 116 } 117 118 119 120 @Override 121 public int onStartCommand(Intent intent, int flags, int startId) 122 { 123 int iRet = super.onStartCommand(intent, flags, startId); 124 System.out.println("BinderService onStartCommand flags:" + flags + " startId:" + startId + " iRet:" + iRet); 125 return iRet; 126 } 127 128 /** 129 * 函数名称 :onUnbind 130 * 功能描述 :解除绑定 131 * 参数说明 : 132 * @param intent 133 * @return 134 * 返回值: 135 * 136 * 修改记录: 137 * 日期 :2012-1-11 下午3:54:05 修改人:gy 138 * 描述 : 139 * 140 */ 141 @Override 142 public boolean onUnbind(Intent intent) 143 { 144 if(t != null) 145 { 146 //中断线程 147 t.interrupt(); 148 } 149 boolean bl = super.onUnbind(intent); 150 System.out.println("BinderService onUnbind bl:" + bl); 151 return bl; 152 } 153 154 /** 155 * 函数名称 :onDestroy 156 * 功能描述 :销毁服务 157 * 参数说明 : 158 * 返回值: 159 * 160 * 修改记录: 161 * 日期 :2012-1-11 下午3:53:59 修改人:gy 162 * 描述 : 163 * 164 */ 165 @Override 166 public void onDestroy() 167 { 168 super.onDestroy(); 169 System.out.println("BinderService onDestroy"); 170 } 171 }
在前台运行服务的步骤
有时候,我们不希望后台服务,被系统在资源不足的情况下,被杀死,所以我们会把服务设定为前台服务(把服务设定为前台服务并不是说服务是可见,而应该理解为:是把服务的优先级设高了),从而让系统不会杀掉它
比如:音乐播放器在后台播放的时候,我们不希望被杀死
服务开始在前台运行:startForeground(int, notification)
服务停止在前台运行:stopForeground(boolean)
1 //启动服务 2 Intent bindIntent = new Intent(Service_Demo4Activity.this, BinderMusicService.class); 3 //绑定到 BinderMusicService 服务 4 /** 5 * bindService方法参数: 6 * 第一个参数:intent 7 * 第二个参数:ServiceConnection(连接到服务器上的服务的连接对象) 8 * 第三个参数:int 9 */ 10 bindService(bindIntent, svcConn, Context.BIND_AUTO_CREATE); 11 12 13 //服务连接对象:定义服务绑定的回调,传递给绑定服务 14 private ServiceConnection svcConn = new ServiceConnection() 15 { 16 /** 17 * 18 * 函数名称 :onServiceConnected 19 * 功能描述 : 服务连接上的时候,这个方法被调用 20 * 参数说明 : 21 * @param name 22 * @param service 从服务器返回的 Binder 对象 23 * 返回值: 24 * 25 * 修改记录: 26 * 日期 :2012-1-12 下午3:45:03 修改人:gy 27 * 描述 : 28 * 29 */ 30 @Override 31 public void onServiceConnected(ComponentName name, IBinder service) 32 { 33 34 strTitle = "播放音乐通知栏标题"; 35 strContent = "播放音乐通知栏内容"; 36 //点击通知时转移内容 37 Intent nfcIntent = new Intent(this, Notification_Message.class); 38 nfcIntent.putExtra("title", title); 39 nfcIntent.putExtra("content", content); 40 41 //设置点击通知时显示内容的类 42 PendingIntent pIntent = PendingIntent.getActivity(Service_Demo4Activity.this, 0, nfcIntent, 43 PendingIntent.FLAG_UPDATE_CURRENT); 44 45 46 Notification nfc = new Notification(); 47 //设置通知在状态栏显示的图标 48 nfc.icon = R.drawable.icon; 49 //当我们点击通知时显示的内容 50 nfc.tickerText = "音乐服务正在前台运行"; 51 //自动终止 52 nfc.flags = Notification.FLAG_AUTO_CANCEL; 53 //通知时发出默认的声音 54 nfc.defaults = Notification.DEFAULT_SOUND; 55 56 //设置通知显示的参数(拉下状态栏后显示的内容) 57 nfc.setLatestEventInfo(Service_Demo4Activity.this, strTitle, strContent, pIntent); 58 59 60 61 //获取绑定对象 62 MyMusicBinder binder = (MyMusicBinder) service; 63 //获取 BinderMusicService 对象 64 bs = binder.getService(); 65 //将服务设置为前台运行 66 bs.startForeground(BIND_AUTO_CREATE, nfc); 67 //调用服务端的方法,这个方法是在服务端执行 68 bs.playMusic(); 69 70 } 71 72 /** 73 * 74 * 函数名称 :onServiceDisconnected 75 * 功能描述 :服务断开的时候 76 * 参数说明 : 77 * @param name 78 * 返回值: 79 * 80 * 修改记录: 81 * 日期 :2012-1-12 下午3:45:24 修改人:gy 82 * 描述 : 83 * 84 */ 85 @Override 86 public void onServiceDisconnected(ComponentName name) 87 { 88 System.out.println("Service_Demo4Activity onServiceDisconnected"); 89 } 90 };