zoukankan      html  css  js  c++  java
  • Service之一常规Service以及生命周期

    阅读时有疑惑的地方:

    1. 继承IntentService类,它本身提供了一个工作者进程,可以接收onStartCommond发送过来的请求,关键是这句话“Stops the service after all start requests have been handled, so you never have to call stopSelf()”,意思是它在所有请求都被处理以后,也就是被onHandleIntent()处理以后,自己就会关闭。是不是说,发送了一个请求,处理了以后,它就关闭了?还是说,非得同时发送了多个请求,或者在onHandlerIntent的处理过程中也持续不断的有请求过来,当这段处理都过去以后,它就自己关掉了?那这样不是一次性的服务吗?万一想隔十分钟调用一次Service,而处理只是一瞬间,那是不可以理解成每次调用,都是重新启动的它。
    2. 停止服务,stopService和stopSelf方法,为了保证当前关闭时,没有新的请求过来导致误关,SDK建议用stopSelf方法来关闭,该方法有一个id的参数,id是onStartCommon的请求ID,这样能够保证关掉的是最后。但是这个id要怎么和stopSelf方法结合起来用呢?是说每次在onStartCommond调用的时候,把最新这一次的startId先放在全局变量里面,然后在其他地方,比如onStartCommond处理完了以后,再调用stopSelf(startId)方法来结束Service。它这时候是不是把这个startId和Service本身生成的最新startId比较,若相同,就可以结束掉Service,否则,就不结束。也就是说,只要有一次请求,不管有没有在Service里面执行,都会相应的生成一个startId。这样就能保证在request没有全部被处理时,无法结束Service.
    3. 要单独处理的话,为啥不直接用线程,而要用Service?


    主要包括以下三个方面:

    1. service概况
    2. 如何创建service
    3. 生命周期

    一、Service概况

      Service是一个可以执行后台操作的应用程序组件,主要是用来执行一些后台的耗时操作,常见比如请求网络、播放音乐、读取文件、读取数据库等。它没有自己的线程,是运行在主线程里面的,也即和UI的那个线程是一样的,因而,在Service里面,一定要记得新起一个线程来做自己想要做的操作。Service主要分成两类:

    1. Service 常规的Service
    2. bindService 绑定方式创建的Service

      区别主要是调用方式不一样,常规的通过startService方法来调用,触发onStartCommond()方法,需要在Service中控制它的结束或者在客户端调用结束的方法来结束;而bindService通过bindService方法来调用,触发onBind()方法,当所有bind的client都unBlind后,会由系统来自动结束掉。

      运行在后台的Service可以被系统给杀掉,而标记为foreground的Service则不可以。在AndroidManifest.xml中的Service节点,定义时,也可以把Service定义成是否允许其它应用程序访问(android:exported属性),以及定义自己的intent filter接受请求。

    二、创建Service

      创建常规的Service主要有两种方式:

    1. 继承Service类。需要自己负责处理从onStartCommond()方法接收到的多个请求,可以针对每个请求单独开一个线程来并行处理;
      package com.example.android.apistudy.service;
      
      
      import android.app.NotificationManager;
      import android.app.PendingIntent;
      import android.app.Service;
      import android.content.Context;
      import android.content.Intent;
      import android.os.Handler;
      import android.os.HandlerThread;
      import android.os.IBinder;
      import android.os.Looper;
      import android.os.Message;
      import android.os.Process;
      import android.support.v4.app.NotificationCompat;
      
      import com.example.android.apistudy.project.R;
      import com.example.android.apistudy.project.ShowInfoActivity;
      
      public class BackGroundService extends Service {
      
          private ServiceHandler mHandler;
          @Override
          public void onCreate(){
              HandlerThread thread=new HandlerThread("mythread",Process.THREAD_PRIORITY_BACKGROUND);
              thread.start();
              
              Looper looper=thread.getLooper();
              mHandler=new ServiceHandler(looper);
              
          }
          @Override
          public int onStartCommand(Intent intent,int flags,int startId){
              Message msg=new Message();
              mHandler.sendMessage(msg);
              return START_STICKY; 
          }
          
          @Override
          public IBinder onBind(Intent arg0) {
              // TODO Auto-generated method stub
              return null;
          }
          @Override
          public void onDestroy(){
              Message msg=new Message();
              mHandler.sendMessage(msg);
          }
          
          private final class ServiceHandler extends Handler{
              
              
              public ServiceHandler(Looper looper){
                  super(looper);
              }
              
              
              @Override
              public void handleMessage(Message msg){
                  NotificationCompat.Builder mBuilder=new NotificationCompat.Builder(getApplicationContext());
                  mBuilder.setSmallIcon(R.drawable.ic_launcher);
                  mBuilder.setContentTitle("Title::::");
                  mBuilder.setContentText("content......");
                  
                  PendingIntent pendingIntent=PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(),ShowInfoActivity.class), 0);
                  mBuilder.setContentIntent(pendingIntent);
                  
                  NotificationManager manager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
                  manager.notify(0, mBuilder.build());
              }
          }
          
          
      }
    2. 继承IntentService类。实现了一个工作者线程,用来管理所有发送过来的请求,并且触发onHandleIntent()方法来处理,但是不适用于请求同时并发的情况,适合一次性的请求操作。
    package com.example.android.apistudy.service;
    
    
    import android.app.IntentService;
    import android.app.NotificationManager;
    import android.app.PendingIntent;
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Handler;
    import android.os.HandlerThread;
    import android.os.IBinder;
    import android.os.Looper;
    import android.os.Message;
    import android.os.Process;
    import android.support.v4.app.NotificationCompat;
    
    import com.example.android.apistudy.project.R;
    import com.example.android.apistudy.project.ShowInfoActivity;
    
    public class BackGroundIntentService extends IntentService {
    
        public BackGroundIntentService() {
            super("backgroundIntentService");
            // TODO Auto-generated constructor stub
        }
    
        
    
        @Override
        protected void onHandleIntent(Intent intent) {
            NotificationCompat.Builder mBuilder=new NotificationCompat.Builder(getApplicationContext());
            mBuilder.setSmallIcon(R.drawable.ic_launcher);
            mBuilder.setContentTitle("Title::::");
            mBuilder.setContentText("content......");
            
            PendingIntent pendingIntent=PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(),ShowInfoActivity.class), 0);
            mBuilder.setContentIntent(pendingIntent);
            
            NotificationManager manager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
            manager.notify(0, mBuilder.build());
        }
    }

        这个通知不会在点了一下以后消失,只有当Service停止以后才会消失。

    三、生命周期

       借用下SDK里面的生命周期图:

        两种创建Service的方式,对应于不同的生命周期。木有onStop回调函数,Service销毁以后,都是触发onDestroy方法。同时,普通的Service也可以通过bind的方式来访问。是否一旦使用bind方式以后,Service就不能被人为给停止掉。

      onStartCommond()方法有三个返回值:

    •  START_NOT_STICKY ,当service被系统给杀掉以后,不会重新创建Service,直到下一次有新的请求过来;
    •  START_STICKY,当Service被系统给杀掉以后,重新创建Service,但是传递进来的intent对象是空值,并不是之前传递过的; 
    •  START_REDELIVER_INTENT,当Service被系统给杀掉以后,重新创建Service,传递进来的intent对象是之前最新一次传递的Intent,适合下载文件的时候使用。 
    看不清未来,那就看脚下。
  • 相关阅读:
    什么样的代码称得上是好代码?
    九年程序人生 总结分享
    Docker入门 第一课 --.Net Core 使用Docker全程记录
    阿里云 Windows Server 2012 r2 部署asp.net mvc网站 平坑之旅
    Visual studio 2015 Community 安装过程中遇到问题的终极解决
    Activiti6.0 spring5 工作流引擎 java SSM流程审批 项目框架
    java 进销存 库存管理 销售报表 商户管理 springmvc SSM crm 项目
    Leetcode名企之路
    24. 两两交换链表中的节点
    21. 合并两个有序链表
  • 原文地址:https://www.cnblogs.com/caiwan/p/2879956.html
Copyright © 2011-2022 走看看