Service 入门

1 Service的概念

Service是android系统提供服务的四种组件之一,是运行于后台的一种服务程序,一般很少与用户交互,没有可视化界面

  • Service不是独立的进程,除非特别指定,Service运行于应用程序的主进程中
  • Service不是线程,因此不能再主线程之外进行工作 

Service主要有以下两个特征

  • 应用程序通知系统需要在后台进行一些操作的组件,通过调用 Context.startService()来启动service,直到service运行完毕或者明确终止
  • 应用程序暴露给其它应用程序功能性接口。通过调用 Context.bindService()建立连接进行通信

2 Service生命周期

Service对象不能自己启动,需要通过某个Activity、Service或者其他Context对象来启动。启动的方法有两种,Context.startService和Context.bindService()。两种方式的生命周期是不同的,具体如下所示。

Context.startService方式的生命周期: 
启动时,startService –> onCreate() –> onStart() 
停止时,stopService –> onDestroy()                                                                                   

Context.bindService方式的生命周期: 
绑定时,bindService  -> onCreate() –> onBind() 
解绑定时,unbindService –>onUnbind() –> onDestory()

3 Local Service

通常情况下,Service是作为应用程序的附属组件,运行于主进程之中,这种情况下,Client与Service的交互就变得非常简单,只需要Client将IBinder对象转换为Service中发布的类对象即可实现对Service中方法的调用

它分以下几个步骤:

a. 在你的 service 类中声明一个内部类来继承 Binder 类。在该内部类中,最好提供一个公共方法来返回你的 service 实例。

b. 在你的 service 类中需要声明一个这个内部类的实例,以供在 onBind() 方法中返回

c. 在 client 端,在 onServiceConnected() 方法中得到从 onBind() 方法中返回的 IBinder 对象,然后可以通过该 对象中的公共方法得到相应的 service 实例,正如 第一个步骤 所说的那样。

d. 在 service 中提供公共方法, 这样就可以在组件(如 Activity 中调用这些公共方法了)

public class LocalService extends Service {
    private NotificationManager mNM;

    // Unique Identification Number for the Notification.
    // We use it on Notification start, and to cancel it.
    private int NOTIFICATION = R.string.local_service_started;

    /**
     * Class for clients to access.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with
     * IPC.
     */
    public class LocalBinder extends Binder {
        LocalService getService() {
            return LocalService.this;
        }
    }

    @Override
    public void onCreate() {
        mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

        // Display a notification about us starting.  We put an icon in the status bar.
        showNotification();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("LocalService", "Received start id " + startId + ": " + intent);
        // We want this service to continue running until it is explicitly
        // stopped, so return sticky.
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        // Cancel the persistent notification.
        mNM.cancel(NOTIFICATION);

        // Tell the user we stopped.
        Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    // This is the object that receives interactions from clients.  See
    // RemoteService for a more complete example.
    private final IBinder mBinder = new LocalBinder();

    /**
     * Show a notification while this service is running.
     */
    private void showNotification() {
        // In this sample, we'll use the same text for the ticker and the expanded notification
        CharSequence text = getText(R.string.local_service_started);

        // Set the icon, scrolling text and timestamp
        Notification notification = new Notification(R.drawable.stat_sample, text,
                System.currentTimeMillis());

        // The PendingIntent to launch our activity if the user selects this notification
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, LocalServiceActivities.Controller.class), 0);

        // Set the info for the views that show in the notification panel.
        notification.setLatestEventInfo(this, getText(R.string.local_service_label),
                       text, contentIntent);

        // Send the notification.
        mNM.notify(NOTIFICATION, notification);
    }
}

上面我们完成了LocalService的定义,它继承与Service,并且实现了继承自Binder的内部类LocalBinder ,用于返回Service实例。那么在客户端,我们来绑定这个Service需要三个参数bindService(intent,conn,Service.BIND_AUTO_CREATE);第一个是Intent;第二个是ServiceConnection对象,我们创建该对象实现其onServiceConnected()和onServiceDisconnected()来判断连接成功或断开连接,第三个参数是如何创建Service,一般指定绑定时自动创建。

private LocalService mBoundService;

private ServiceConnection mConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
        // This is called when the connection with the service has been
        // established, giving us the service object we can use to
        // interact with the service.  Because we have bound to a explicit
        // service that we know is running in our own process, we can
        // cast its IBinder to a concrete class and directly access it.
       //当Service连接成功时调用此方法,因为我们明确Service运行于当前进程中,不需要处理进程间通信
       //因此我们可以直接将IBinder对象转换为具体类,并且直接使用
     //这里的参数service就是在service中定义的LocalBinder
        mBoundService = ((LocalService.LocalBinder)service).getService(); // Tell the user about this for our demo. Toast.makeText(Binding.this, R.string.local_service_connected, Toast.LENGTH_SHORT).show(); } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. // Because it is running in our same process, we should never // see this happen. mBoundService = null; Toast.makeText(Binding.this, R.string.local_service_disconnected, Toast.LENGTH_SHORT).show(); } }; void doBindService() { // Establish a connection with the service. We use an explicit // class name because we want a specific service implementation that // we know will be running in our own process (and thus won't be // supporting component replacement by other applications). bindService(new Intent(Binding.this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE); mIsBound = true; } void doUnbindService() { if (mIsBound) { // Detach our existing connection. unbindService(mConnection); mIsBound = false; } } @Override protected void onDestroy() { super.onDestroy(); doUnbindService(); }

 

 

 

posted @ 2012-06-21 09:25  Johnny Yan  阅读(176)  评论(0)    收藏  举报