zoukankan      html  css  js  c++  java
  • 整理之Service

    Service

    基础

    一个Service的基本结构
    class MyService : Service() {   
        private val mBinder = MyBinder()
        
        override fun onCreate() {
            super.onCreate()
        }
    
        override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
            return super.onStartCommand(intent, flags, startId)
        }
    
        override fun onBind(intent: Intent): IBinder {
            return mBinder
        }
    
        override fun onUnbind(intent: Intent?): Boolean {
            return super.onUnbind(intent)
        }
    
        override fun onDestroy() {
            super.onDestroy()
        }
        
        class MyBinder:  IBinder() {
            //实现对Service的操作,如下载操作的开始暂停等
        }
    }
    
    <service android:name=".myservice"
                android:enabled="true"
                android:exported="true"
                android:icon="@drawable/background_blue"
                android:label="string"
                android:process="string"
                android:permission="string">
     </service>
    

    启动和关闭:启动后无法操作

    val intent = Intent(this, MyService::class)
    startService(intent)
    stop(service)
    //每次调用startService都会调用一次onStartCommand,但是onCreate只会调用一次
    //只有调用stopService/stopSelf和被系统杀死才会停止服务,startServicec 并不依附于启动它的Context
    

    绑定和解除绑定:可以通过Binder进行操作

    private val mBinder = MyService.MyBinder()
    private val connection = ServiceConnection() {
        @Override
        fun onServiceConnected(name: ComponentName, service: IBinder) {
            mBinder = service as MyService.MyBinder
        }
        @Override
        onServiceDisconnected(name: ComponentName) { }
    }
    val intent = Intent(this, MyService::class)
    bindService(intent, connection, Service.BIND_AUTO_CREATE)
    unbindService(service)
    //bindService时不会调用onStartCommand
    //当Context不存在后,Service也会终止(配置改变时也会停止Service)
    

    两种启动方式的生命周期:

    Service生命周期

    Android5.0后,隐式启动Service $color{blue}文字颜色{blue}$

    <service  
        android:name="com.dbjtech.acbxt.waiqin.UploadService"  
        android:enabled="true" >  
        <intent-filter android:priority="1000" >  
            <action android:name="com.dbjtech.myservice" />  
        </intent-filter>  
    </service> 
    
    val intent = Intent().apply {
        setAction("com.android.ForegroundService");
        setPackage(getPackageName());//设置应用的包名
    }
    startService(intent);
    

    粘性服务与非粘性服务

    服务的粘性体现在:当服务被系统杀死后,粘性服务会自动重启并执行onStartCommand,非粘性服务不会。

    通过onStartCommand的返回值来设置是否粘性,可选择的值为:

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

    默认情况下,通过startService启动的服务为粘性的。

    前台服务

    参考这篇文章

    官方描述:前台服务是那些被认为用户知道(用户所认可的)且在系统内存不足的时候不允许系统杀死的服务。前台服务必须给状态栏提供一个通知,它被放到正在运行(Ongoing)标题之下——这就意味着通知只有在这个服务被终止或从前台主动移除通知后才能被解除。

    使用方法

    在onCommand中创建通知

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
      // 在API11之后构建Notification的方式
      Notification.Builder builder = new Notification.Builder
        (this.getApplicationContext()); //获取一个Notification构造器
      Intent nfIntent = new Intent(this, MainActivity.class);
    
      builder.setContentIntent(PendingIntent.
        getActivity(this, 0, nfIntent, 0)) // 设置PendingIntent
        .setLargeIcon(BitmapFactory.decodeResource(this.getResources(),
          R.mipmap.ic_large)) // 设置下拉列表中的图标(大图标)
        .setContentTitle("下拉列表中的Title") // 设置下拉列表里的标题
        .setSmallIcon(R.mipmap.ic_launcher) // 设置状态栏内的小图标
        .setContentText("要显示的内容") // 设置上下文内容
        .setWhen(System.currentTimeMillis()); // 设置该通知发生的时间
      
      Notification notification = builder.build(); // 获取构建好的Notification
      notification.defaults = Notification.DEFAULT_SOUND; //设置为默认的声音
    
      return super.onStartCommand(intent, flags, startId);
    }
    

    启动与停止:

    // 参数一:唯一的通知标识;参数二:通知消息。
    startForeground(110, notification);// 开始前台服务
    stopForeground(true);// 停止前台服务--参数:表示是否移除之前的通知
    

    IntentService

    参考这篇文章
    1.与Service的区别

    Service运行在主线程,内部不能执行耗时操作。但IntentService在执行onCreate 操作的时候,内部开了一个线程,去你执行你的耗时操作

    2.特点

    会创建独立的 worker 线程来处理所有的 Intent 请求

    会创建独立的 worker 线程来处理 onHandleIntent() 方法实现的代码,无需处理多线程问题

    所有请求处理完成后,IntentService 会自动停止,无需调用 stopSelf() 方法停止 Service

    为 Service 的 onBind() 提供默认实现,返回 null

    为 Service 的 onStartCommand 提供默认实现,将请求 Intent 添加到队列中

    3.使用

    编写类:

    class MyIntentService : IntentService("MyIntentService") {
        override fun onHandleIntent(intent: Intent?) {
            when (intent?.action) {
                。。。
            }
        }
    }
    

    注册:

    <service android:name="com.example.intentservicetest.MyService" />
    

    启动:

    val intent = Intent(MainActivity.this, MyService.class);
    startService(intent);
    //所有的请求的处理都在一个工作线程中完成 , 它们会交替执行(但不会阻塞主线程的执行),一次只能执行一个请求。
    
    4.执行过程
    • 每次启动该服务并不是马上处理你的工作,而是首先会创建对应的Looper、Handler,并且在 MessageQueue 中添加附带客户 Intent 的 Message 对象。
    • 当 Looper 发现有 Message 的时候,会在onHandleIntent((Intent)msg.obj) 中得到 Intent 对象,调用你的处理程序,处理完后即会停止自己的服务。

    Intent 的生命周期跟你的处理的任务是一致的,所以这个类用下载任务中非常好,下载任务结束后服务自身就会结束退出。

  • 相关阅读:
    数据结构--线性表和链表的基础知识
    OC基础--字符串
    iOS开发知识梳理博文集
    OC基础--数据类型与表达式
    数据结构概述
    数据结构--栈和队列基础知识
    NodeJS Get/Post 参数获取
    NodeJS + express 添加HTTPS支持
    NodeJS 获取系统时间 并格式化输出
    Node.Js + Express 搭建服务器
  • 原文地址:https://www.cnblogs.com/lizhenxin/p/12441394.html
Copyright © 2011-2022 走看看