• 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,适合下载文件的时候使用。 
    看不清未来,那就看脚下。
  • 相关阅读:
    Android-使用AIDL挂断电话
    新变化---转战新博客
    Spring Cloud Config 分布式配置中心【Finchley 版】
    Spring Boot2.0 整合 Kafka
    Spring Cloud 分布式链路跟踪 Sleuth + Zipkin + Elasticsearch【Finchley 版】
    Spring MVC 5 + Thymeleaf 基于Java配置和注解配置
    【机器学习】使用gensim 的 doc2vec 实现文本相似度检测
    【机器学习】SKlearn + XGBoost 预测 Titanic 乘客幸存
    【深度学习】keras + tensorflow 实现猫和狗图像分类
    iScroll.js 向上滑动异步加载数据回弹问题
  • 原文地址:https://www.cnblogs.com/caiwan/p/2879956.html
Copyright © 2020-2023  润新知