zoukankan      html  css  js  c++  java
  • Service(Local Service)简介

    一、Service的作用

    主要用于在后台处理一些耗时的逻辑操作,或者去执行某些长期运行的操作。

    二、Service的创建

    1.主要方法

    IBinder onBind(Intent intent):必须实现方法。返回一个IBinder对象,程序通过该对象与Service交互

    (Service类似Activity有自己的生命周期)

    void onCreate():当Service第一次被创建的时候回调

    void onDestroy():当Service被关闭的时候回调

    int onStartCommand(Intent intent, int flags,int startId) :每次调用startService(int)→(启动Service的方法)时候回调

    返回值

    1):START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。 
    2):START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务 
    3):START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。 
    4):START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

    参数flags表示启动服务的方式):

    START_FLAG_REDELIVERY:如果你实现onStartCommand()来安排异步工作或者在另一个线程中工作, 那么你可能需要使用START_FLAG_REDELIVERY来让系统重新发送一个intent。这样如果你的服务在处理它的时候被Kill掉, Intent不会丢失. 
    START_FLAG_RETRY:表示服务之前被设为START_STICKY,则会被传入这个标记。 
    启动service的时候,onCreate方法只有第一次会调用,onStartCommand和onStart每次都被调用。onStartCommand会告诉系统如何重启服务,如判断是否异常终止后重新启动,在何种情况下异常终止
    .

    boolean onUnbind():与绑定的所有客户端断开连接(Service可与Activity绑定 稍后讲)的时候回调

    2.调用流程——跟Activity类的创建相似

    ①子类继承Service,重写方法

    ②在AndroidManifest.xml注册(因为需要用Intent启动Service,所以Service类必须注册)

    ③调用启动方法启动Service(详见3.启动Service)

    3.启动Service

    类别 区别
    1.startService 启动的服务

    主要用于启动一个服务执行后台任务,不进行通信(无绑定与无法交互)。

    停止服务使用stopService。

    在Activity所在进程被Kill的时候,该服务依然在运行

    2.bindService 启动的服务

    该方法启动的服务要进行通信(与绑定的Acitivty交互)。

    停止服务使用unbindService。

    主进程被Kill后,服务便会终止。

    3.startService 同时也 bindService 启动的服务 停止服务应同时使用stopService与unbindService(顺序由创建顺序决定)
     注:每种方法的生命周期也是不同的  详见4.Servier的生命周期                为什么需要这么多种Service详见  6.两种方法的用处

    ①方法一的启动与关闭(startService)

    步骤一:

    /*步骤一:子类继承Service类*/
    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 flag, int startId) {
    
            super.onStart(intent, flag,startId);
    
        }
    
         
        @Override
    
        public void onDestroy() {
    
            super.onDestroy();
    
        }
    
    }
    View Code

    步骤二:

    <service android:name=".LocalService1">
      <!--intent-filter可设可不设   跟注册Activity的方式是一样的-->
      <intent-filter>
         <action android:name="com.chen.service.First_Service"/>
      </intent-filter>
    </service>
    View Code

    步骤三:

    // 启动一个 Service
    Intent intent = new Intent();
    intent.setAction("com.chen.service.First_Service");//设置Intent
    startService(intent);
    
    ...
    
    // 停止一个 Service
    
    stopService(intent);
    View Code

    ②方法二的启动与关闭(bindService)
    启动方法:bindService(Intente service,ServiceConnection conn,int flags);

    service:intent对象

    conn:监听绑定者与Service的状况。当连接成功时回调该对象的onServiceConnected(ComponentName name,IBinder service)方法。

            失败时候调用onServiceDisconnected(ComponextName name)(:用unBindService()方法断开并不会被调用)。

            :onServiceConnected返回的IBinder对象是Service类中的onBind(Intent intent)的返回值

    flags:指定绑定是是否自动创建Service(如果Service还未创建)   0(不自动创建)或 BIND_AUTO_CREATE(自动创建)

    步骤一:借用方法一的步骤一经过修改

    //未修改部分
    @Override
    
    public IBinder onBind(Intent intent) {
    
         return null;
    
     }
    
    //修改部分 
    private int count = 5;
    
    public class MyBinder extends Binder{
      public int getCount(){
        //获取当前Service的count值;
        return count;
      }
    }
    
    @Override
    public IBinder onBind(Intent intent) {
         
         return new MyBinder;
    
    }
    View Code

    步骤二:在Activity中启动并绑定Service

    LocalService1.MyBinder binder;//定义Binder,获取Service的Binder。因为是内部类
    
    //定义一个ServiceConnection对象
    private ServiceConntection connection = new ServiceConnection(){
    @Override
          public void onServiceConnected(ComponentName name, IBinder service) {
              mMyBinder = (LocalService1.MyBinder)service;//获取binder
              Log.d("MainActivity","Service is connected");
          }
    
          @Override
          public void onServiceDisconnected(ComponentName name) {
              Log.d("MainActivity","Service is disconnect");
          }
    };
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          Intent intent = new Intent(this,LocalService1.class);
          bindService(intent,mConnection,BIND_AUTO_CREATE);//绑定到程序
    
          int count = mBinder.getCount();//利用Binder获取Service内部信息
    }
    
    @Override
    protected void onDestory(){
          unbindService(conn);//解除绑定
    }
    View Code

    4.不同方法的生命周期

    ①.调用startService(左图),调用bindService(右图)

    当多次调用startService方法:系统只会调用onStartCommand()方法

          当多次调用bindService方法:系统只会调用onBind()方法

          隐藏方法:onRebind()  产生条件:1.由startService()方法启动 2.重写onUnbind方法 return true

    ②先调用startService()再调用bindService()方法,再调用unbindService()

    生命周期:onCreate()->onStartCommand()->onBind()->onUnbind()[重写时reuturn true]->onRebuild()

    但是发现没有调用onDestory()方法:说明bindService()只是通信绑定在Acitivty,但生命周期并不与Activity绑定。(这就可以又能交互又能不在Activity消失后Service也跟着消失)

    5、在什么情况下使用 startService 或 bindService 或 同时使用startService 和 bindService

    如果你只是想要启动一个后台服务长期进行某项任务那么使用 startService 便可以了。

    如果你想要与正在运行的 Service 取得联系,那么有两种方法,一种是使用 broadcast ,另外是使用 bindService ,前者的缺点是如果交流较为频繁,容易造成性能上的问题,并且 BroadcastReceiver 本身执行代码的时间是很短的(也许执行到一半,后面的代码便不会执行),而后者则没有这些问题,因此我们肯定选择使用 bindService(这个时候你便同时在使用 startService 和 bindService 了,这在 Activity 中更新 Service 的某些运行状态是相当有用的)。

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

    6、两种办法的具体用处

    类别 区别 应用
    前台服务 会在通知一栏显示 ONGOING 的 Notification, 当服务被终止的时候,通知一栏的 Notification 也会消失,这样对于用户有一定的通知作用。常见的如音乐播放服务。
    后台服务 默认的服务即为后台服务,即不会在通知一栏显示 ONGOING 的 Notification。 当服务被终止的时候,用户是看不到效果的。某些不需要运行或终止提示的服务,如天气更新,日期同步,邮件同步等。

    7.与Thread的区别 详见  http://www.cnblogs.com/newcj/archive/2011/05/30/2061370.html

    疑问:Service用startService()能不能在应用程序退出的时候执行。如果能的话Remote Service是干什么用的。

  • 相关阅读:
    获取指定字符传的长度或者高度
    检测身份证号码是否合法
    tabbar添加小红点
    单例的简单构造
    iOS程序内发短信
    多项式加法运算 使用链表实现
    链表的数组实现
    使用链表实现堆栈
    使用链表实现堆栈
    求最大子列和的几种方法
  • 原文地址:https://www.cnblogs.com/rookiechen/p/5268795.html
Copyright © 2011-2022 走看看