Services
Service是长时间运行在后台,不与用户交互的组件
Service与Activity选择标准:某个程序组件在运行时需要向用户呈现某种界面,或者程序需要用户交互,需要使用Activity,否则将要考虑Service,比如访问网络,文件IO操作,大数据的数据操作,音乐播放等。在默认情况下,Service应运行在应用程序进程的主线程中,若在Service中处理一些网络链接等耗时操作,应将这些任务存放在单独的线程中执行,避免阻塞用户界面
用Home键Service继续执行,结束进程Service结束,启动服务,不启动多线程会阻塞,服务不是一个新的进程也不是一个新的线程,与当前进程绑定
Service只有在系统资源不足时,才可以被销毁,需要注意的是Service被绑定时,很少被销毁,服务是前台服务时,几乎不销毁
1.service开发步骤:
继承Service子类;在manifest.xml文件中配置该Service;配置时可通过<intent-filter>指定可以被哪些Intent启动
2.Service的两种形式
Started
以startService()启动,一旦启动运行在后台,即使启动它的Activity对象消失,一般来说,执行单一的操作,且无返回值
Bound
以bindService()启动,Bound提供了客户端接口,允许组件与服务互动,发送请求,收到回复,甚至进行进程间通信。只要组件绑定到服务,服务就开始运行,允许多个组件同事绑定到服务,但是只有所有组件都取消绑定后,服务才销毁
Service通过调用一对回调函数,可同时工作在以上两种形式:onStartCommand()与onBind()
注意:
Service运行在主进程的主线程上,并没有为它创建自己的线程或分立进程,这就意味着若Service进行一些Cpu密集型工作或阻塞工作,必须新开线程进行处理,避免发生ANR
3.Sevice类的回调函数
onStartCommand()
由其他组件调用StartService()时自动回调,可由其他组件调用 stopSelf()或
stopService()停止此Service
onBind()
由其他组件调用bindService()时自动回调,必须通过返回IBinder提供客户端与服务的接口,如果你不想实现绑定,可返回null
onCreate()
Service第一次被创建时,如果Service已经运行,则此函数不会被调用。onCreate()被调用在onStartCommand()与onBind()之前
onDestroy()
4.创建一个Started Service
Started Service是通过组件调用startService(),进而调用Service的onStartCommand()方法的Service,当一个Service被Start,它的生命周期就是独立的,不会因为启动它的组件销毁而销毁。当Service工作完成后,可以通过调用stopSelf()销毁自己,也可以通过别的组件调用stopService()来销毁。由其他组件调用startService()传递的Intent由Service的onStartCommand()来接收
继承IntentService类
不需要Service同时处理多个请求时,继承IntentService
(1)创建一个独立于主线程的默认的工作线程来执行将所有Intent交付给onStartCommand()
(2)创建一个队列,实现同一时刻只有一个Intent到onHandleIntent()
(3)所有请求完成后,停止Service,所以不必调用StopSelf()
(4)提供onBind()回调的实现,默认返回NULL
(5)提供onStartCommand()回调的实现,发送Intent到工作队列,之后到onHandleIntent()实现
5.创建Bound Service
Bound Service允许应用组件调用BoundService()绑定来创建长时间链接
需要与用户组间交流或者暴露应用功能给其他应用程序时选用BoundService(),必须实现onBind()回调函数,且需返回
IBinder
控件通过 bindService()与服务绑定,unbindServi
ce()解除与服务器的绑定
6.发送用户通知给用户
Once running, a service can notify the user of events using Toast Notifications or Status Bar Notifications.服务一旦运行,就可以使用Toast Notifications或Status Bar Notifications通知用户事件
7.Service运行在前台
Notification notification = new Notification(R.drawable.icon,getText(R.string.ticker_text),System.currentTimeMillis()); Intent notificationIntent = new Intent(this, ExampleActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); notification.setLatestEventInfo(this, getText(R.string.notification_title), getText(R.string.notification_message), pendingIntent); startForeground(ONGOING_NOTIFICATION_ID, notification);
startForeground()与 stopForeground()
8.Service生命周期
public class ExampleService extends Service { int mStartMode; // indicates how to behave if the service is killed IBinder mBinder; // interface for clients that bind boolean mAllowRebind; // indicates whether onRebind should be used @Override public void onCreate() { // The service is being created } @Override public int onStartCommand(Intent intent, int flags, int startId) { // The service is starting, due to a call to startService() return mStartMode; } @Override public IBinder onBind(Intent intent) { // A client is binding to the service with bindService() return mBinder; } @Override public boolean onUnbind(Intent intent) { // All clients have unbound with unbindService() return mAllowRebind; } @Override public void onRebind(Intent intent) { // A client is binding to the service with bindService(), // after onUnbind() has already been called } @Override public void onDestroy() { // The service is no longer used and is being destroyed } }
备注:1.Service被Destroy后,在Service中启动的线程不会被终止
2.即使在onStartCommand()函数启动就调用stopSelf(),onStartCommand()函数也需要执行完成
9.onStartCommand有4种返回值:
START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统将会把它置为started状态,系统不会自动重启该服务,直到startService(Intent intent)方法再次被调用;。
START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
10.备注
boundService绑定服务并不会新开线程(等待验证)
stopService()与unBound()是否会必定调用distory()
android:process=":remote"根据必要情况建立新的进程
onBound()与onServiceConnected(),onBound()先执行
onUnbound()与onServiceDisconnect(),谁先执行?
Service与线程区别:
逻辑上,认为需要后台操作,但跟现在主线程操作通讯频繁,联系紧密,建议多线程,若能从逻辑上区分开来,用Service