Android--Service类分析

    技术2022-05-19  21

    Android中的服务和windows中的服务是类似的东西.服务(service)主要用于两个目的:后台运行和跨进程访问。通过启动一个服务,可以在不显示界面的前提下在后台运行指定的任务,这样可以不影响用户做其他事情。通过AIDL服务可以实现不同进程之间的通信,这也是服务的重要用途之一。

    一、service

    一个服务是 不是 一个单独的进程。  一个服务是 不是 一个线程。 

    service的两种模式(startService()/bindService()不是完全分离的)

    · 它可以启动并运行,直至有人停止了它或它自己停止。在这种方式下,它以调用Context.startService()启动,而以调用Context.stopService()结束。它可以调用Service.stopSelf() 或 Service.stopSelfResult()来自己停止。不论调用了多少次startService()方法,你只需要调用一次stopService()来停止服务。 

    · 它可以通过自己定义并暴露出来的接口进行程序操作。客户端建立一个到服务对象的连接,并通过那个连接来调用服务。连接以调用Context.bindService()方法建立,以调用 Context.unbindService()关闭。多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载它。 

     

    当一个服务组件被创建时,有可能是以上两种原因,系统实际上做的是实例化该组件并调用它 的onCreate() 和任何其他适当的回调主线上。 它是由服务来实现这些行为与适当的操作,如创建一个辅助线程在它执行其。

     

    二、Service生命周期

    Service与Activity一样,也有一个从启动到销毁的过程。Service的生命周期过程只有3个阶段:

    1、创建服务

    2、开始服务

    3、销毁服务

    一个服务实际上是一个继承android.app.Service的类。

    onCreate() 该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。

    onStart(Intent intent,int startId)  该方法在服务开始时调用,onStart方法会被调用多次

    onDestroy()该方法在服务被终止时调用,整个生命周期中植被调用一次。

     

    · 服务的完整生命周期始于调用onCreate()而终于onDestroy()方法返回。如同activity一样,服务在onCreate()里面进行它自己的初始化,而在onDestroy()里面释放所有资源。比如说,一个音乐回放服务可以在onCreate()中创建播放音乐的线程, 而在onDestroy()中停止这个线程。 

    · 服务的活跃生命周期始于调用onStart()。这个方法用于处理传递给startService()的Intent对象。音乐服务会打开Intent来探明将要播放哪首音乐,并开始播放。

    服务停止时没有相应的回调方法──不存在onStop()方法。

     

    onCreate()和onDestroy()方法在所有服务中都会被调用,不论它们是由Context.startService()还是由Context.bindService()所启动的。

    如果一个服务允许别的进程绑定,则它还会有以下额外的回调方法以供实现:

    IBinder onBind(Intent intent) boolean onUnbind(Intent intent) void onRebind(Intent intent)

    传递给bindService的Intent的对象也会传递给onBind()回调方法,而传递给unbindService()的Intent对象同样传递给onUnbind()。如果服务允许绑定,onBind()将返回一个供客户端与服务进行交互的通讯渠道。如果有新的客户端连接至服务,则onUnbind()方法可以要求调用onRebind() 。

    服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。

    使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。

    使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。

    如果打算采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。

    如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。

    采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。

    onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用。

    采用Context.bindService()方法启动服务时只能调用onUnbind()方法解除调用者与服务解除,服务结束时会调用onDestroy()方法。

    当然一个正在运行的服务也有可能被销毁onDestroy():这是发生在系统内存不足时

    注意:在AndroidManifest.xml文件中的<application>节点里对服务进行配置:<service android:name=".SMSService" />

    一个简单的服务类:

     

    view source print ? 01public class LocalService extends Service { 02       03    @Override 04    public void onCreate() { 05       Log.i("LocalService", "onCreate()"); 06        super.onCreate(); 07    } 08   09    @Override 10    public void onStart(Intent intent,int startId) { 11        Log.i("LocalService", "Received start id " + startId + ": " + intent); 12           13        super.onStrart(); 14    } 15   16    @Override 17    public void onDestroy() { 18       Log.i("LocalService", "onDestroy()"); 19       super.onDestory(); 20    } 21   22    @Override 23    public IBinder onBind(Intent intent) { 24        return null; 25    } 26}

     

    在我们的客户端启动上面的服务:startService()启动

     

    view source print ? 01public class  StartAService extends Activity { 02    @Override 03    public void onCreate(Bundle savedInstanceState) {  04        ...... 05        Button button =(Button) this.findViewById(R.id.button); 06        button.setOnClickListener(new View.OnClickListener(){ 07    public void onClick(View v) { 08        Intent intent = new Intent(StartAService.this, SMSService.class); 09        startService(intent); 10    }});         11    } 12}  

     

    BindService()启动继承的Service类实现onBind()方法

     

    view source print ? 1public class LocalService extends Service { 2    private NotificationManager mNM;  //通知管理对象 view source print ? 01    public class LocalBinder extends Binder { 02        LocalService getService() {  //获取被连接的服务对象 03            return LocalService.this; 04        } 05    } 06       07    @Override 08    public void onCreate() { 09  super.onCreate(); 10        mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); 11   12        // Display a notification about us starting.  We put an icon in the status bar. 13        showNotification();//当创建一个服务时执行一个通知 14    } 15   16    @Override 17    public int onStartCommand(Intent intent, int flags, int startId) { 18          19        Log.i("LocalService", "Received start id " + startId + ": " + intent); 20        // We want this service to continue running until it is explicitly 21        // stopped, so return sticky. 22        return START_STICKY; 23    } 24   25    @Override 26    public void onDestroy() { 27        // Cancel the persistent notification. 28        mNM.cancel(R.string.local_service_started);  //关闭通知 29   30        // Tell the user we stopped. 31        Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show(); 32  super.onDestroy(); 33    } 34   35    @Override 36    public IBinder onBind(Intent intent) { 37        return mBinder; 38    } 39   40    // This is the object that receives interactions from clients.  See 41    // RemoteService for a more complete example. 42    private final IBinder mBinder = new LocalBinder(); 43   44    /** 45     * Show a notification while this service is running. 46     */ 47    private void showNotification() { 48        // In this sample, we'll use the same text for the ticker and the expanded notification 49        CharSequence text = getText(R.string.local_service_started); 50   51        // Set the icon, scrolling text and timestamp 52        Notification notification = new Notification(R.drawable.stat_sample, text, 53                System.currentTimeMillis()); 54   55        // The PendingIntent to launch our activity if the user selects this notification 56        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, 57                new Intent(this, LocalServiceController.class), 0); 58   59        // Set the info for the views that show in the notification panel. 60        notification.setLatestEventInfo(this, getText(R.string.local_service_label), 61                       text, contentIntent); 62   63        // Send the notification. 64        // We use a layout id because it is a unique number.  We use it later to cancel. 65        mNM.notify(R.string.local_service_started, notification);  // 66    } 67}

     

     

     

    view source print ? 1public class BindAService extends Activity { 2       private boolean mIsBound;    view source print ? 1 private LocalService boundService; view source print ? 1ServiceConnection conn = new ServiceConnection() { 2public void onServiceConnected(ComponentName name, IBinder service)  //参数二是一个IBinder类型的变量, view source print ? 1{

     

     

    view source print ? 1//将该参数转换成MyService.MyBinder对象,并使用MyBinder类中的getService方法获得MyService对象。在获得MyService对象后, view source print ? 1//就可以在Activity中随意操作MyService了 2          3//在这可以与连接的服务交互 view source print ? 1  

     

     

    view source print ? 1 

     

    view source print ? 1<BR>

     

    view source print ? 1boundService= ((LocalService.LocalBinder)service).getService();                        // Tell the user about this for our demo.           view source print ? 1         Toast.makeText(LocalServiceBinding.this, R.string.local_service_connected,  Toast.LENGTH_SHORT).show(); 2    } 3    public void onServiceDisconnected(ComponentName name) { 4                  //连接服务意外中断处

     

     

    view source print ? 1bundService= null;            view source print ? 1                      Toast.makeText(LocalServiceBinding.this, R.string.local_service_disconnected,  Toast.LENGTH_SHORT).show(); 2    } 3     }; 4    @Override public void onCreate(Bundle savedInstanceState) {   view source print ? 1...................... view source print ? 1  view source print ? 1Button button1 = (Button)findViewById(R.id.unbind);        view source print ? 1   button1.setOnClickListener(mUnbindListener); 2    Button button =(Button) this.findViewById(R.id.button); 3    button.setOnClickListener(new View.OnClickListener(){ 4public void onClick(View v) { 5    Intent intent = new Intent(BindAService.this, SMSService.class); 6    bindService(intent, conn, Context.BIND_AUTO_CREATE);  //把服务绑定 7    //unbindService(conn);//解除绑定 8}});      view source print ? 1 private OnClickListener mUnbindListener = new OnClickListener() {        view source print ? 1 public void onClick(View v) {         view source print ? 1   if (mIsBound) {                // Detach our existing connection.                view source print ? 1 unbindService(mConnection);                 view source print ? 1mIsBound = false;     //销毁       view source print ? 1 }         view source print ? 1}     view source print ? 1      };    2    } 3}


    最新回复(0)