Service基础使用

news2024/12/27 20:19:07

Service简介

Service是什么

Service是一个应用组件,它用来在后台完成一个时间跨度比较大的工作,且没有关联任何界面
Service的生命周期方法在主线程运行。

使用场景

service用于在后台完成用户指定的操作。

  1. 访问网络;
  2. 播放音乐;
  3. 文件IO操作;
  4. 大数据量的数据库操作;

特点

  1. Service在后台运行,不用于用户进行交互。
  2. 即使应用退出,服务也不会停止。
  3. 在默认情况下,Service运行在应用程序的主线程/UI线程中,如果需要在Service中处理一些网络连接等耗时的操作,需要将这些任务放在子线程中处理,避免阻塞用户界面。

分类

Local Service(本地服务)

Service对象与Service的启动者在同个进程中运行,两者的通信是进程内通信。

Remote Service(远程服务)

Service对象与Service的启动者不在同一个进程中运行,这时存在一个进程间通信的问题,Android专门为此设计了AIDL来实现进程间通信。

Service的生命周期

Service继承了Context

public class MyService extends Service {
    private static String TAG = "JJWorld.MyService";
    public MyService() {
        Log.i(TAG,"MyService..");
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        Log.i(TAG,"onBind...");
        return new Binder();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG,"onCreate..");

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG,"onDestroy..");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG,"onStartCommand...");
        return super.onStartCommand(intent, flags, startId);
    }
}

注意:
如果当前service已经启动,再次调用startService,service生命周期重走onStartCommand;

  • 多个服务启动请求会导致多次对服务的 onStartCommand() 进行相应的调用。但是,如要停止服务,只需一个服务停止请求(使用stopSelf() 或 stopService())即可。

Android链接可见。
在这里插入图片描述

Service使用

使用清单文件声明服务

如同对 Activity 及其他组件的操作一样,您必须在应用的清单文件中声明所有服务。
如要声明服务,请添加 元素作为 元素的子元素。下面是示例:

<manifest ... >
  ...
  <application ... >
      <service android:name=".ExampleService" />
      ...
  </application>
</manifest>

启动与停止

一般启停

startService与stopService

startService(new Intent(this,MyService.class));
stopService(new Intent(this,MyService.class));

绑定启停

bindService与unbindService

if (serviceConnection == null){
    serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.i(TAG,"onServiceConnected..");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i(TAG,"onServiceConnected..");
        }
    };
    bindService(new Intent(this, MyService.class), serviceConnection,BIND_AUTO_CREATE);
}else {
    Log.i(TAG,"you have already bind service");
}
if (serviceConnection!=null){
    unbindService(serviceConnection);
    serviceConnection = null;
}else {
    Log.i(TAG,"you have not bind service");
}

停止服务

启动服务必须管理自己的生命周期。换言之,除非必须回收内存资源,否则系统不会停止或销毁服务,并且服务在 onStartCommand() 返回后仍会继续运行。服务必须通过调用 stopSelf() 自行停止运行,或由另一个组件通过调用 stopService() 来停止它。

为避免浪费系统资源和消耗电池电量,请确保应用在工作完成之后停止其服务。如有必要,其他组件可通过调用 stopService() 来停止服务。即使为服务启用绑定,如果服务收到对 onStartCommand() 的调用,您始终仍须亲自停止服务。

创建绑定服务

绑定服务允许应用组件通过调用 bindService() 与其绑定,从而创建长期连接。此服务通常不允许组件通过调用 startService() 来启动它。

如要创建绑定服务,您需通过实现 onBind() 回调方法返回 IBinder,从而定义与服务进行通信的接口。然后,其他应用组件可通过调用bindService()来检索该接口,并开始调用与服务相关的方法。服务只用于与其绑定的应用组件,因此若没有组件与该服务绑定,则系统会销毁该服务。您不必像通过onStartCommand() 启动的服务那样,以相同方式停止绑定服务。

多个客户端可以同时绑定到服务。完成与服务的交互后,客户端会通过调用 unbindService() 来取消绑定。如果没有绑定到服务的客户端,则系统会销毁该服务。

创建启动服务

IntentService

当不考虑让服务同时处理多个任务时,可以使用扩展 IntentService 类
IntentService 类会执行以下操作:

  • 创建默认的工作线程,用于在应用的主线程外执行传递给 onStartCommand() 的所有 Intent。
  • 创建工作队列,用于将 Intent 逐一传递给 onHandleIntent() 实现,这样您就永远不必担心多线程问题。
  • 在处理完所有启动请求后停止服务,因此您永远不必调用 stopSelf()。
  • 提供 onBind() 的默认实现(返回 null)。
  • 提供 onStartCommand() 的默认实现,可将 Intent 依次发送到工作队列和 onHandleIntent() 实现。

IntentService示例

public class HelloIntentService extends IntentService {
    private String TAG = "JJWorld.HelloIntentService";

    public HelloIntentService() {
        super("HelloIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        // Normally we would do some work here, like download a file.
        // For our sample, we just sleep for 5 seconds.
        try {
            Thread.sleep(5000);
            Log.i(TAG,"onHandleIntent...");
        } catch (InterruptedException e) {
            // Restore interrupt status.
            Thread.currentThread().interrupt();
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG,"onCreate....");
    }

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        Log.i(TAG,"onStartCommand....");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG,"onDestroy....");
    }
}

调用代码

Log.i(TAG,"testService...");
 //线程工厂
 ThreadFactory factory = new ThreadFactory() {
     @Override
     public Thread newThread(Runnable r) {
         Thread thread = new Thread(r);
         return thread;
     }
 };
 Activity activity = this;
 ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 5, 10, TimeUnit.SECONDS, new LinkedBlockingDeque<>(5),
         factory, new ThreadPoolExecutor.AbortPolicy());
 for (int i = 0; i < 10; i++) {
     executor.execute(new Runnable() {
         @Override
         public void run() {
             startService(new Intent(activity,HelloIntentService.class));
         }
     });
 }

表现

2023-02-10 19:55:45.973 24630-24630/cn.jj.autostart I/JJWorld.MyServiceActivity: testService...
2023-02-10 19:55:45.991 24630-24630/cn.jj.autostart I/JJWorld.HelloIntentService: onCreate....
2023-02-10 19:55:45.992 24630-24630/cn.jj.autostart I/JJWorld.HelloIntentService: onStartCommand....
2023-02-10 19:55:45.993 24630-24630/cn.jj.autostart I/JJWorld.HelloIntentService: onStartCommand....
2023-02-10 19:55:45.994 24630-24630/cn.jj.autostart I/JJWorld.HelloIntentService: onStartCommand....
2023-02-10 19:55:45.997 24630-24630/cn.jj.autostart I/JJWorld.HelloIntentService: onStartCommand....
2023-02-10 19:55:46.007 24630-24630/cn.jj.autostart I/JJWorld.HelloIntentService: onStartCommand....
2023-02-10 19:55:46.011 24630-24630/cn.jj.autostart I/JJWorld.HelloIntentService: onStartCommand....
2023-02-10 19:55:46.014 24630-24630/cn.jj.autostart I/JJWorld.HelloIntentService: onStartCommand....
2023-02-10 19:55:46.017 24630-24630/cn.jj.autostart I/JJWorld.HelloIntentService: onStartCommand....
2023-02-10 19:55:46.020 24630-24630/cn.jj.autostart I/JJWorld.HelloIntentService: onStartCommand....
2023-02-10 19:55:46.036 24630-24630/cn.jj.autostart I/JJWorld.HelloIntentService: onStartCommand....
2023-02-10 19:55:50.992 24630-12566/cn.jj.autostart I/JJWorld.HelloIntentService: onHandleIntent...
2023-02-10 19:55:55.995 24630-12566/cn.jj.autostart I/JJWorld.HelloIntentService: onHandleIntent...
2023-02-10 19:56:01.003 24630-12566/cn.jj.autostart I/JJWorld.HelloIntentService: onHandleIntent...
2023-02-10 19:56:06.010 24630-12566/cn.jj.autostart I/JJWorld.HelloIntentService: onHandleIntent...
2023-02-10 19:56:11.018 24630-12566/cn.jj.autostart I/JJWorld.HelloIntentService: onHandleIntent...
2023-02-10 19:56:16.024 24630-12566/cn.jj.autostart I/JJWorld.HelloIntentService: onHandleIntent...
2023-02-10 19:56:21.033 24630-12566/cn.jj.autostart I/JJWorld.HelloIntentService: onHandleIntent...
2023-02-10 19:56:26.042 24630-12566/cn.jj.autostart I/JJWorld.HelloIntentService: onHandleIntent...
2023-02-10 19:56:31.048 24630-12566/cn.jj.autostart I/JJWorld.HelloIntentService: onHandleIntent...
2023-02-10 19:56:36.056 24630-12566/cn.jj.autostart I/JJWorld.HelloIntentService: onHandleIntent...
2023-02-10 19:56:36.066 24630-24630/cn.jj.autostart I/JJWorld.HelloIntentService: onDestroy....

Remote Service(远程服务)

进程间通信AIDL

每个应用程序都运行在自己的独立进程中,并且可以启动另一个应用进程的服务,而且经常需要在不同的进程间传递数据对象

Android平台上,一个进程不能直接访问另一个进程的内存空间,所以想要对话,需要将对象分解成操作系统可以理解的基本单元,并且有序的通过进程边界。
AIDL(Android Interface Definition Language)
用于生成可以在Android设备上两个进程之间进行进程间通信的代码。

远程服务客户端

绑定

Intent intent = new Intent("cn.jj.autostart.service.MyService.action");
 if (serviceConnection == null){
     serviceConnection = new ServiceConnection() {
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {

         }

         @Override
         public void onServiceDisconnected(ComponentName name) {

         }
     };
     Log.i(TAG,"bindRemoteService....");
     bindService(intent, serviceConnection,BIND_AUTO_CREATE);
 }else {
     Log.i(TAG,"bindRemoteService but serviceConnection is null....");
 }

解绑

if (serviceConnection!=null){
    unbindService(serviceConnection);
    serviceConnection = null;
    Log.i(TAG,"unbindRemoteService....");
}else {
    Log.i(TAG,"unbindRemoteService but serviceConnection not build....");
}

可能遇到错误

java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=cn.jj.autostart.service.MyService.action }

解决
对隐式意图添加包名

Intent intent = new Intent("cn.jj.autostart.service.MyService.action").setPackage("cn.jj.autostart");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/337054.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

指针的步长及意义(C语言基础)

指针的步长及意义 文章目录指针的步长及意义指针变量1后偏移的字节数不同指针[解引用](https://so.csdn.net/so/search?q解引用&spm1001.2101.3001.7020)时取出的字节数不同其他例子不同类型的指针有何不同的意义指针变量1后跳跃字节数量不同解引用的时候&#xff0c;取出…

虹科方案 | 制药环境中冰箱温度记录的最佳实践——全集成温度监测系统

有效监测冰箱温度是药店、医疗中心和制药实验室的一项重要要求。保持准确的冰箱温度记录对所有储存处方药和疫苗的设施来说是必不可少的&#xff0c;但实现这一目标的最佳方法是什么&#xff1f;● 制药机构需要在特定的温度下储存疫苗和处方药&#xff0c;以保证病人的安全并确…

微信小程序-常用api

文章目录微信小程序-常用api路由wx.switchTab(Object object)wx.navigateTo(Object object)wx.navigateBack(Object object)wx.redirectTo(Object object)提示wx.showToast(Object object)wx.showModal(Object object)wx.showLoading(Object object)wx.showActionSheet(Object …

了解线程池newFixedTheadPool

什么是线程池 操作系统 能够进行运算 调度 的最小单位。线程池是一种多线程处理形式。 为什么引入线程池的概念 解决处理短时间任务时创建和销毁线程代价较大的弊端&#xff0c;可以使用线程池技术。 复用 饭店只有一个服务员和饭店有10个服务员 线程池的种类 newFixedThea…

Linux下载安装MySQL8的方式,并开放外网访问

作者主页&#xff1a;Designer 小郑 作者简介&#xff1a;Java全栈软件工程师一枚&#xff0c;来自浙江宁波&#xff0c;负责开发管理公司OA项目&#xff0c;专注软件前后端开发&#xff08;Vue、SpringBoot和微信小程序&#xff09;、系统定制、远程技术指导。CSDN学院、蓝桥云…

软考的证书含金量高吗?

因为该考试还具有水平考试性质&#xff0c;报考任何级别不需要学历、资历条件&#xff0c;只要达到相应的专业技术水平就可以报考相应的级别。考试合格者将颁发由中华人民共和国人力资源和社会保障部、工业和信息化部用印的计算机技术与软件专业技术资格&#xff08;水平&#…

Flutter Web:图片相关及跨域问题

加载网络图片 在flutter web上也可以使用Image这个widget来加载显示图片。但是涉及到网络图片的时候就可能会出现问题&#xff0c;现象是不显示图片&#xff0c;控制台报错&#xff1a; Failed to load network image. Image URL: https://cdnimagelive.knowbox.cn/image/7841…

2023年上半年软考高项报名条件-信息系统项目管理师

信息系统项目管理师是全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff08;简称软考&#xff09;项目之一&#xff0c;是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试&#xff0c;既属于国家职业资格考试&#xff0c;又是职称资…

62 序列到序列学习(seq2seq)【动手学深度学习v2】

62 序列到序列学习&#xff08;seq2seq&#xff09;【动手学深度学习v2】 深度学习学习笔记 学习视频&#xff1a;https://www.bilibili.com/video/BV16g411L7FG/?spm_id_fromautoNext&vd_source75dce036dc8244310435eaf03de4e330 一个句子翻译到另一个句子。 seq2seq 最早…

经典网络模型系列——Swin-Transformer详细讲解与代码实现

经典网络模型系列——Swin-Transformer详细讲解与代码实现一、网路模型整体架构二、Patch Partition模块详解三、Patch Merging模块四、W-MSA详解五、SW-MSA详解masked MSA详解六、 Relative Position Bias详解七、模型详细配置参数八、重要模块代码实现&#xff1a;1、Patch P…

Android开发【金三银四】之OKhttp网络通讯socket

一、SOCKS代理 全能代理&#xff0c;就像有很多跳线的转接板&#xff0c;它只是简单地将一端的系统连接到另外一端。支持多种协议&#xff0c;包括http、ftp请求及其它类型的请求。它分socks 4 和socks 5两种类型&#xff0c;socks 4只支持TCP协议而socks 5支持TCP/UDP协议&am…

Java后端开发功能模块思路

文章目录前言一、查找接口及参数信息1.1 找访问路径1.2 参数及返回结果信息1.3 编写功能模块函数二、代码设计思路三、总结前言 对于正在学习Java后端开发的同学来说&#xff0c;对于Java后端功能模块的开发过程及思路要有一个整体清晰的流程。才能保证在开发过程中更加的顺畅…

哪些数据可以用在二手车买卖中?

近期&#xff0c;商务部副部长盛秋平表示&#xff0c;将着力稳定和扩大汽车消费&#xff0c;支持新能源汽车购买使用&#xff0c;扩大二手车流通。还将打通二手车信息平台&#xff0c;推广上海的汽车全生命周期信息平台和中国汽车流通协会有关经验做法&#xff0c;建设全国性的…

Python-项目实战--飞机大战-游戏背景(5)

目标背景交替滚动的思路确定显示游戏背景1.背景交替滚动的思路确定游戏启动后&#xff0c;背景图像会连续不断地向下方移动在视觉上产生英雄的飞机不断向上方飞行的错觉 -- 在很多跑酷类游戏中常用的套路游戏的背景不断变化游戏的主角位置保持不变1.1实现思路分析解决办法创建两…

计算机视觉框架OpenMMLab开源学习(三):图像分类实战

前言&#xff1a;本篇主要偏向图像分类实战部分&#xff0c;使用MMclassification工具进行代码应用&#xff0c;最后对水果分类进行实战演示&#xff0c;本次环境和代码配置部分省略&#xff0c;具体内容建议参考前一篇文章&#xff1a;计算机视觉框架OpenMMLab开源学习&#x…

计算机网络整理-问答

1. 程序工作的时候网络各层的状态 如下图所示&#xff1a; 1. TCP 在进行三次握手的时候&#xff0c;IP 层和 MAC 层对应都有什么操作呢&#xff1f; TCP 三次握手是通过在传输层建立连接的一个过程&#xff0c;在这个过程中&#xff0c;TCP 和 IP 层、MAC 层都起到了重要的…

ChatGPT API 本地如何调用

本文将会介绍&#xff0c;如何找到API文档和相应语言SDK&#xff0c;并使用PHP调用SDK实现本地请求API的完成过程及遇到的问题和解决方法。 API文档 1.打开官网 ChatGPT: Optimizing Language Models for Dialogue 2.找到API 3.查看文档 4.找到sdk库 OpenAI API 5.主流语言 …

2023年软考什么时候考试?

2023年软考各科目考试时间安排已确定&#xff01;中国计算机技术职业资格网发布了《2023年度计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试工作计划》&#xff0c;具体见下文。2023年度计算机软件资格考试&#xff08;初级、中级、高级&#xff09;上半年考试…

树莓派4b Raspberry Pi 4安装以前内置Python3.7版本的系统出现的一系列问题记录

今天想要重装树莓派系统&#xff0c;想装那种内置Python3.7版本的系统&#xff0c;从网上找到镜像源后烧录进去出现一系列问题&#xff1a; 烧录系统开机后&#xff0c;首先就出现报错&#xff1a; 上面显示一个问题就是&#xff1a;start4x.elf: is not compatible&#xff0…

Django自定义模板标签的使用详解

目录 1.创建子应用&#xff1a;python manage.py startapp test01 2.进行相关的配置 3.在新建的test01文件下创建urls.py(此处名称可变但注意上图) 4.在test01文件下创建名称为templatetags的文件夹 5.templatetags文件下继续创建几个py文件如下图​编辑 6.views视图函数…