Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1081702
  • 博文数量: 226
  • 博客积分: 10000
  • 博客等级: 上将
  • 技术积分: 2504
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-21 14:12
文章分类

全部博文(226)

文章存档

2011年(1)

2010年(2)

2009年(68)

2008年(4)

2007年(27)

2006年(124)

我的朋友

分类: LINUX

2009-05-26 15:46:51

什么是Service

Android引入了Service的概念是为了处理后台进程。Service不实现任何用户界面。最 常见的例子如:媒体播放器程序,它可以在转到后台运行的时候仍然能保持播放歌曲;或者如文件下载程序,它可以在后台执行文件的下载。

它跟Activity的级别差不多,但是他不能自己运行,需要通过某一个Activity或者其他Context对象来调用, Context.startService() Context.bindService()


Service
的生命周期

Service的生命周期方法比Activity少一些,只有onCreate, onStart, onDestroy
我们有两种方式启动一个Service,他们对Service生命周期的影响是不一样的。两种启动Service的方式有所不同。这里要说明一下的是如果你在ServiceonCreate或者onStart做一些很耗时间的事情,最好在Service里启动一个线程来完成,因为Service是跑在主线程中,会影响到你的UI操作或者阻塞主线程中的其他事情。

创建一个Service
Android
中已经定义了一个 ‘Service’类,所有其他的Service都继承于该类。Service类中定义了一系列的生命周期相关的方法,如: onCreate(), onStart(), onDestroy()

 

启动Service

有了 Service 类我们如何启动他呢,有两种方法:

  • Context.startService()
  • Context.bindService()

在同一个应用任何地方调用 startService() 方法就能启动 Service 了,然后系统会回调 Service 类的 onCreate() 以及 onStart() 方法。这样启动的 Service 会一直运行在后台,直到 Context.stopService() 或者 selfStop() 方法被调用。另外如果一个 Service 已经被启动,其他代码再试图调用 startService() 方法,是不会执行 onCreate() 的,但会重新执行一次 onStart()

另外一种 bindService() 方法的意思是,把这个 Service 和调用 Service 的客户类绑起来,如果调用这个客户类被销毁,Service 也会被销毁。用这个方法的一个好处是,bindService() 方法执行后 Service 会回调上边提到的 onBind() 方发,你可以从这里返回一个实现了 IBind 接口的类,在客户端操作这个类就能和这个服务通信了,比如得到 Service 运行的状态或其他操作。如果 Service 还没有运行,使用这个方法启动 Service 就会 onCreate() 方法而不会调用 onStart()

用其他方式启动 Service

其实不光能从 Activity 中启动 Service ,还有一个很有用的方法是接收系统的广播,这就要用到 Receiver 。在 Mainfest 文件中配置你得 Receiver 能接收什么样的广播消息,那么即使你得程序没有显示给用户,你的 Service 也能启动。你要做的就是继承 android.content.BroadcastReceiver ,然后实现 onReceive(Context context, Intent intent) 方法,就可以启动你得 Service 了。这里不能 bindService 因为一个 Receiver 是一个短暂存在的对象,所以 bind 是没有什么意义的。

这种方法启动service,你可以参考我以前的一篇文章android activity/service开机后自动运行


接下来用一个例子来演示一下service的创建以及调用。

首先是创建service这一部分,代码如下:



import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

/**
 * This is an example of implementing an application service that runs locally
 * in the same process as the application. The {@link LocalServiceController}
 * and {@link LocalServiceBinding} classes show how to interact with the
 * service.
 *
 *

Notice the use of the {@link NotificationManager} when interesting things
 * happen in the service. This is generally how background services should
 * interact with the user, rather than doing something more disruptive such as
 * calling startActivity().
 */
public class LocalService extends Service {
    
    private NotificationManager mNM;
    private MediaPlayer mp;

    /**
     * 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);
        
        Log.i("Zx", "Duration");

        // Display a notification about us starting. We put an icon in the status bar.

        showNotification();
    }

    @Override
    public void onDestroy() {
        // Cancel the persistent notification.

        mNM.cancel(R.string.local_service_started);

        // Tell the user we stopped.

        Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();
        
        mp.stop();
    }

    @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, Demo.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.

        // We use a layout id because it is a unique number. We use it later to cancel.

        mNM.notify(R.string.local_service_started, notification);
        
        //add music player here

        mp = MediaPlayer.create(this, R.raw.test_cbr);
        mp.start();
    }

}


至于如何调用就很简单了,你可以在需要启动service的地方:



      Intent i = new Intent();
      i.setClass(Demo.this, LocalService.class);
      startService(i);

阅读(1519) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~