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()与服务绑定,unbindService()解除与服务器的绑定

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

 

posted @ 2014-02-07 17:03  Eudora_Do  阅读(541)  评论(0编辑  收藏  举报