通过android:process指定的远程服务是运行在一个独立的进程里,比如说接入消息推送之类的,需要建立长连接。

以下默认是local Service

  • 服务适用于不需要和用户交互,又需要长期运行的任务。

  • 服务的运行不依赖于任何用户界面,即使程序切换到了后台,服务仍能正常运行。

  • 服务并不是运行在一个独立的进程中,而是依赖创建服务时所在的应用程序进程(默认运行在主线程中)。

  • 服务并不会自动创建线程,需要手动开启线程,才能执行耗时操作。

  • 每个服务只会存在一个实例,无论多次startService还是bindService获取到的实例

  • 服务启动了就会一直处于运行状态,除非执行stopService或者stopSelf (调用unbind不会停止service)

  • 需要在AndroidManifest中声明

既然服务和线程没有任何关系,而且服务工作在主线程中,不能执行耗时操作(无论是按键超时、服务超时、广播超时都会造成ANR);那服务有啥用呢?让服务执行耗时操作需要手动开启线程,线程不也可以长时间运行么?

官方解释:

A service is simply a component that can run in the background, even when the user is not interacting with your application, so you should create a service only if that is what you need. If you must perform work outside of your main thread, but only while the user is interacting with your application, you should instead create a new thread.

If you create a Thread or an Executor in an Activity of your app, this leads to unpredictable results, since a simple screen orientation change will disrupt things, since the Activity will no longer be around when the Thread completes its task.You could use AsyncTask to handle this, but what if your app needs this Background Thread to be started from not just an Activity, but a notification or another component?

In these cases, Android Services are the right Android component to use to match up the Thread’s lifecycle with that of the Service’s lifecycle.

1、Thread 的运行是独立于Activity的,也就是说当一个Activity被finish之后,如果你没有主动停止Thread或者Thread里的run方法没有执行完毕的话,Thread 也会一直执行。在线程执行完毕,我们可以手动stopself让service结束,避免浪费资源。

2、当Activity被finish之后,不再持有该Thread的引用,也就不能在不同的Activity中对同一Thread进行控制。而我们可以在任何有Context的地方调用Context.startService、Context.stopService、Context.bindService,Context.unbindService 来操作service。

Android多线程编程

Android的单线程模型

1.不能阻塞UI线程。 所有耗时操作(网络、数据库、大文件等)都应该放在子线程中操作

2.不能在UI线程之外访问Android UI 。因为更新UI的方法不是线程安全的(更新时会进行线程检查)

所以一般在子线程中执行耗时操作,再回到主线程( UI线程 )更新UI。(一般通过Handler进行操作)

Handle模型

Handle/Message/MessageQueue/Looper 实现线程间交互

1、每个线程都只有一个MessageQueue,一个Looper

2、handle.sendMessage()会将message放入当前线程的Messagequeue中,等待执行

3、looper.loop()遍历MessageQueue中的每个message,执行msg.target.handleMessage(),回调handler的handleMessage()

详情请见:

服务的生命周期

  • onCreate() 服务创建的时候调用(只调用一次)

  • onStartCommand() 服务每次启动的时候调用(虽然每次startService都会调用一次,但每个服务都只会存在一个实例)

  • onDestroy() 服务销毁时调用(如果startService & bindService,则要调用stopService & unbindService,才回调onDestroy)

执行1-2 日志:onCreate -> onStartCommand -> onDestroy

执行1-1-2 日志:onCreate -> onStartCommand -> onStartCommand -> onDestroy (onStartCommand会执行多次)

执行3-4 日志:onCreate -> onBind -> onServiceConnected -> onDestroy (直接bindService创建的服务不会执行onStartCommand)

执行1-3-4-2 日志:onCreate -> onStartCommand -> onBind -> onServiceConnected -> onDestroy (既执行了startService,又执行了bindService)

执行4 日志:service not Registed exception (没有bind,不能执行unbind)

执行1-4 日志:service not Registed exception

执行1-3-4-4 日志:onCreate -> onStartCommand -> onBind -> onServiceConnected -> service not Registed exception (已经unbind之后,未bind,也不能unbind)

在activity中执行3,退出activity,报错has leaked ServiceConnection,会执行onDestroy

在activity中执行1,退出activity,不报错,不会执行onDestroy,服务启动了就会一直处于运行状态,除非执行stopService 或者 stopSelf

当activity 和 service 绑定之后,就可以调用该服务中 binder 提供的方法了

  1. startServic
val intent = Intent(this, MyService::class.java)
startService(intent)
复制代码
  1. stopService
val intent = Intent(this, MyService::class.java)
stopService(intent)
复制代码
  1. bindService
val intent = Intent(this, MyService::class.java)
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
复制代码

4.unbindService

unbindService(serviceConnection)
复制代码

服务的使用

通过startService 和stopService只是启动和结束服务,但是activity和service并没有建立关联,activity并不能定点让service干什么工作。

由bindService来建立 activity 和 service 之间的联系,onBind返回的IBinder类向上转型,为service中定义的Binder类,得到了Binder实例,就可以调用Binder中定义的方法。

var downloadBinder: MyService.DownLoadBinder? = nullval serviceConnection = object  : ServiceConnection{override fun onServiceDisconnected(name: ComponentName?) {LogUtils.e(" onServiceDisconnected invoke!!!")}override fun onServiceConnected(name: ComponentName?, service: IBinder?) {LogUtils.e(" onServiceConnected invoke!!!")downloadBinder = service as MyService.DownLoadBinder? //向上转型downloadBinder?.startDownLoad() //调用bind的方法downloadBinder?.getProgress()}
}
复制代码

MyService.java

public class MyService extends Service {private DownLoadBinder mBinder = new DownLoadBinder();public static class DownLoadBinder extends Binder {public void startDownLoad() {Log.e("zhen", "startDownLoad");}public void getProgress() {Log.e("zhen", "getProgress");}}@Overridepublic void onCreate() {super.onCreate();Log.e("zhen", "onCreate");}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.e("zhen", "onStartCommand");return super.onStartCommand(intent, flags, startId);}@Nullable@Overridepublic IBinder onBind(Intent intent) {Log.e("zhen", "onBind");return mBinder;}@Overridepublic void onDestroy() {super.onDestroy();Log.e("zhen", "onDestroy");}
}
复制代码

AndroidManifest中注册

android:exported="true" 表示允许除当前程序之外的其它程序访问这个服务,默认为true

android:enabled="true" 表示启动这个服务,默认为true

<service android:name=".module.service.MyService"android:exported="true"android:enabled="true"/>
复制代码

转载于:https://juejin.im/post/5b611a7d6fb9a04f87521e72

Service 深度解析相关推荐

  1. 推荐:微服务架构的深度解析!

    通过采用微服务架构,企业最大的收益是帮助内部IT建设沿着可演进的方向发展.支持灵活扩展.降低运维成本.快速响应业务变化. 这些底层技术能力的提升让业务更加敏捷.成本可控,企业也可以从中获得技术红利和市 ...

  2. Hologres揭秘:深度解析高效率分布式查询引擎

    简介:从阿里集团诞生到云上商业化,随着业务的发展和技术的演进,Hologres也在持续不断优化核心技术竞争力,为了让大家更加了解Hologres,我们计划持续推出Hologers底层技术原理揭秘系列, ...

  3. 微服务架构深度解析与最佳实践

    微服务架构深度解析与最佳实践 微服务架构的概念,现在对于大家应该都不陌生,无论使用 Apache Dubbo.还是 Spring Cloud,都可以去尝试微服务,把复杂而庞大的业务系统拆分成一些更小粒 ...

  4. 25岁阿里120W年薪架构师推荐学习的750页微服务架构深度解析文档

    前言 当前,微服务架构在国内正处于蓬勃发展的阶段,无论是大型互联网公司还是传统的IT企业,纷纷采用微服务架构构建系统. 在过去几年里,DevOps.云原生.面向演进式架构等理念已经深入人心,围绕微服务 ...

  5. 深度解析Istio系列之策略与遥测篇

    注:以下讲述的案例环境场景是基于Kubernetes环境基础上部署的istio环境. 涉及到的Pilot和Envoy的了解请参考深度解析Istio系列之流量控制篇,本文重点在于介绍Mixer. Mix ...

  6. Retrofit2深度解析

    Retrofit2深度解析 〇.简介 本文基于implementation 'com.squareup.retrofit2:retrofit:2.5.0' 编写而成. Retrofit是很好的开源项目 ...

  7. 云计算-7-Dockerfile深度解析CMD和ENTRYPOINT指令

    云计算-7-Dockerfile深度解析 CMD CMD指令 Docker不是虚拟机,Docker镜像启动后就是容器,容器是进程,启动的时候需要指定运行的程序和参数,CMD指令的作用就是用于指定容器进 ...

  8. 震网(Stuxnet)病毒深度解析:首个攻击真实世界基础设施的病毒

    摘要:震网病毒主要是通过改变离心机的转速,来破坏离心机,并影响生产的浓缩铀质量. 本文分享自华为云社区<[安全技术]震网(Stuxnet)病毒深度解析:首个攻击真实世界基础设施的病毒(1)[原创 ...

  9. Spring源码深度解析(郝佳)-学习-源码解析-基于注解bean定义(一)

    我们在之前的博客 Spring源码深度解析(郝佳)-学习-ASM 类字节码解析 简单的对字节码结构进行了分析,今天我们站在前面的基础上对Spring中类注解的读取,并创建BeanDefinition做 ...

最新文章

  1. 用Jsp来实现文件下载功能的几种方式
  2. python安装pip-安装pip的三种方法
  3. python opencv检测人脸
  4. 51cto 网站挑错,你来干?
  5. SignalTap II逻辑分析仪的使用
  6. C++Builder中开发Activex
  7. RT-Thread uart串口设备驱动代码结构剖析
  8. C语言面试题分享(5)
  9. JavaScript表单
  10. javacv 人脸检测_使用JavaCV进行手和手指检测
  11. php调用美图接口,网易美图 API 接口调用与请求方法详细教程
  12. html语言的address,HTML: address 标签
  13. mssql sqlserver 优化注意事项:
  14. win10服务器只显示4g内存,64位win10识别到了4G内存,却只用了3.1G,为什么?
  15. (六)K8S中HostPath、EmptyDir、ConfigMap、Secret、Downward API用法
  16. 个人博客_温州个人博客_Duing-冬忆个人博客
  17. already opened by ClassLoader
  18. 2021-09-10 参数计算
  19. 登录起凡是显示计算机拒绝无法连接,怎么解决win10系统无法连接打印机并显示未指定设备问题?...
  20. ChatGPT使用案例之自然语言处理

热门文章

  1. overridePendingTransition
  2. ImageView、Bitmap的属性android:scaleType
  3. android Comparator的使用
  4. 做程序开发的你如果经常用Redis,这些问题肯定会遇到
  5. Python中import和from......import的区别
  6. 后端接口的幂等性(转)
  7. 每天一个Linux命令之date
  8. 简单区分Vmware的三种网络连接模式(bridged、NAT、host-only)
  9. appcon 图标打包
  10. ava method org.apache.struts2.components.Form.getValidators(String) threw an exception when invoke