Service知识汇总

作者: jnxc1888 | 来源:发表于2017-02-07 16:13 被阅读52次

    Service概述

    由于手机屏幕的限制,通常情况下在同一时刻仅有一个应用程序处于激活状态,并能够显示在手机屏幕上,因此,应用程序需要一种机制,在没有用户界面的情况下,能够长时间在后台运行,实现应用程序的特定功能,并能够处理事件或更新数据.Android系统提供了(Service)服务组件,它不直接与用户进行交互,却能够长期在后台运行。有很多情况需要使用Service,典型的例子就是:MP3播放器。

    Service非常适用于无需用户干预,且需要长期运行的后台功能。Service没有用户界面,有利于降低系统资源。而且Service比Activity具有更高的优先级,只有在系统资源极度匮乏的情况下,android系统才可能清理掉一部分service来保证系统的运行,而这种情况却又轻易不会出现。即使Service被系统终止了,在系统资源恢复后Service也将自动恢复运行状态,因此可以认为Service是在系统中永久运行的组件。Service除了实现后台服务功能,还可以用于进程间通信,解决两个不同Activity应用程序进程之间的调用和通信问题。

    启动方式

    startService/bindService

    生命周期

    startService 只启动服务,调用者与服务之前并没有绑定,当程序关闭以后,服务扔在运行

    bindService 启动并且绑定调用者与服务,当程序关闭以后,服务也随之关闭

    一、startService

    1.startService -> onCreate -> onStartCommand , 调用者需要调用stopService关闭服务,否则服务一直在后台运行。

    2.关闭Service时直接回调onDestroy方法。

    3.用该方法创建多次Service,onCreate只会被调用一次,但onStartCommand会被调用多次。

    二、bindService

    1.bindService -> onCreate -> onBind, 调用者调用unbindService方法或者调用者的Context不存在了(被关闭)的时候Service会被关闭

    2.Service关闭回调onUnbing -> onDestory

    3.多次调用bindService只会被调用一次onCreate和onBind

    既使用startService又使用bindService的情况:

    如果一个Service又被启动又被绑定,则该Service会一直在后台运行。首先不管如何调用,onCreate始终只会调用一次。对应startService调用多少次,Service的onStart方法便会调用多少次。Service的终止,需要unbindService和stopService同时调用才行。不管startService与bindService的调用顺序,如果先调用unbindService,此时服务不会自动终止,再调用stopService之后,服务才会终止;如果先调用stopService,此时服务也不会终止,而再调用unbindService或者之前调用bindService的Context不存在了(如Activity被finish的时候)之后,服务才会自动停止。

    那么,什么情况下既使用startService,又使用bindService呢?

    如果你只是想要启动一个后台服务长期进行某项任务,那么使用startService便可以了。如果你还想要与正在运行的Service取得联系,那么有两种方法:一种是使用broadcast,另一种是使用bindService。前者的缺点是如果交流较为频繁,容易造成性能上的问题,而后者则没有这些问题。因此,这种情况就需要startService和bindService一起使用了。

    另外,如果你的服务只是公开一个远程接口,供连接上的客户端(Android的Service是C/S架构)远程调用执行方法,这个时候你可以不让服务一开始就运行,而只是bindService,这样在第一次bindService的时候才会创建服务的实例运行它,这会节约很多系统资源,特别是如果你的服务是远程服务,那么效果会越明显(当然在Servcie创建的是偶会花去一定时间,这点需要注意)。

    与调用者通讯

    startService:只能通过广播(Broadcast)通讯

    bindService:与调用者绑定的时候需传入ServiceConnection实例,可通过实现了IBinder接口的对象进行通讯

    代码示例:

    startService

    public class LocalService1 extends Service {
        /**
        * onBind 是 Service 的虚方法,因此我们不得不实现它。
        * 返回 null,表示客服端不能建立到此服务的连接。
        */
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
        
        @Override
        public void onCreate() {
            super.onCreate();
        }
        
        @Override
        public void onStartCommand(Intent intent, int startId, int flags) {
            super.onStartCommand(intent, startId, flags);
        }
        
        @Override
        public void onDestroy() {
            super.onDestroy();
        }
    }
    

    bindService

    public class LocalService extends Service {
    /**
    * 在 Local Service 中我们直接继承 Binder 而不是 IBinder,因为 Binder 实现了 IBinder 接口,这样我们可以** 少做很多工作。
    */
    public class SimpleBinder extends Binder{
    /**
    * 获取 Service 实例
    * @return
    */
    public LocalService getService(){
    return LocalService.this;
    }
    
    public int add(int a, int b){
    return a + b;
    }
    }
    
    public SimpleBinder sBinder;
    
    @Override
    public void onCreate() {
    super.onCreate();
    // 创建 SimpleBinder
    sBinder = new SimpleBinder();
    }
    
    @Override
    public IBinder onBind(Intent intent) {
    // 返回 SimpleBinder 对象
    return sBinder;
    }
    }
    

    上面的代码关键之处,在于 onBind(Intent) 这个方法 返回了一个实现了 IBinder 接口的对象,这个对象将用于绑定Service 的 Activity 与 Local Service 通信。

    下面是 Activity 中的代码:

    public class Main extends Activity {
        private final static String TAG = "SERVICE_TEST";
        private ServiceConnection sc;
        private boolean isBind;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            sc = new ServiceConnection() {
                @Override
                public void onServiceDisconnected(ComponentName name) {
                }
        
                @Override
                public void onServiceConnected(ComponentName name, IBinder service) {
                    LocalService.SimpleBinder sBinder = (LocalService.SimpleBinder)service;
                    Log.v(TAG, "3 + 5 = " + sBinder.add(3, 5));
                    Log.v(TAG, sBinder.getService().toString());
                }
            };
    
            findViewById(R.id.btnBind).setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    bindService(new Intent(Main.this, LocalService.class), sc, Context.BIND_AUTO_CREATE);
                    isBind = true;
                }
            });
    
            findViewById(R.id.btnUnbind).setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(isBind){
                        unbindService(sc);
                        isBind = false;
                    }
                }
            });
        }
    }
    

    拓展

    远程服务 AIDL

    相关文章

      网友评论

        本文标题:Service知识汇总

        本文链接:https://www.haomeiwen.com/subject/qecmittx.html