zoukankan      html  css  js  c++  java
  • AndroidService类分析

       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" />

    一个简单的服务类:

    public class LocalService extends Service {
        
        @Override
        public void onCreate() {
           Log.i("LocalService", "onCreate()");
            super.onCreate();
        }
    
        @Override
        public void onStart(Intent intent,int startId) {
            Log.i("LocalService", "Received start id " + startId + ": " + intent);
            
            super.onStrart();
        }
    
        @Override
        public void onDestroy() {
           Log.i("LocalService", "onDestroy()");
           super.onDestory();
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    }
    


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

    public class  StartAService extends Activity {
        @Override
        public void onCreate(Bundle savedInstanceState) { 
            ......
            Button button =(Button) this.findViewById(R.id.button);
            button.setOnClickListener(new View.OnClickListener(){
    	public void onClick(View v) {
    		Intent intent = new Intent(StartAService.this, SMSService.class);
    		startService(intent);
    	}});        
        }
    }
    
    
     

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

    public class LocalService extends Service {
        private NotificationManager mNM;  //通知管理对象
        public class LocalBinder extends Binder {
            LocalService getService() {  //获取被连接的服务对象
                return LocalService.this;
            }
        }
        
        @Override
        public void onCreate() {
      super.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(R.string.local_service_started);  //关闭通知
    
            // Tell the user we stopped.
            Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();
      super.onDestroy();
        }
    
        @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, LocalServiceController.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);  //
        }
    }
    

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

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

     

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

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


  • 相关阅读:
    多表联合查询,利用 concat 模糊搜索
    order by 中利用 case when 排序
    Quartz.NET 3.0.7 + MySql 动态调度作业+动态切换版本+多作业引用同一程序集不同版本+持久化+集群(一)
    ASP.NET Core 2.2 基础知识(十八) 托管和部署 概述
    ASP.NET Core 2.2 基础知识(十七) SignalR 一个极其简陋的聊天室
    ASP.NET Core 2.2 基础知识(十六) SignalR 概述
    ASP.NET Core 2.2 基础知识(十五) Swagger
    ASP.NET Core 2.2 基础知识(十四) WebAPI Action返回类型(未完待续)
    linux磁盘管理 磁盘查看操作
    linux磁盘管理 文件挂载
  • 原文地址:https://www.cnblogs.com/sardine/p/1834788.html
Copyright © 2011-2022 走看看