当前位置:   article > 正文

23 个安卓重难点突破,带你吃透 Service 知识点「长达 1W+ 字」(1)_安卓service

安卓service

这篇文章主要针对 Service 相关的知识点,进行详细的梳理,祝大家食用愉快!

文章目录

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

方便大家学习,我在 GitHub 建立了 仓库


第一篇:Service 是什么


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.1 什么是 Service

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • Service (服务) 是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件。
  • 服务可由其他应用组件启动(如 Activity ),服务一旦被启动将在后台一直运行,即使启动服务的组件( Activity )已销毁也不受影响。
  • 此外,组件可以绑定到服务,以与之进行交互,甚至是执行进程间通信 ( IPC )。

1.2 Service 通常总是称之为 “后台服务”

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 其中 “后台” 一词是相对于前台而言的,具体是指:其本身的运行并不依赖于用户可视的 UI 界面
  • 因此,从实际业务需求上来理解,Service 的适用场景应该具备以下条件:
  1. 并不依赖于用户可视的 UI 界面(当然,这一条其实也不是绝对的,如前台 Service 就是与 Notification 界面结合使用的)

  2. 具有较长时间的运行特性

  3. 注意: 是运行在主线程当中的

1.3 服务进程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 服务进程是通过 startService() 方法启动的进程,但不属于前台进程和可见进程。例如,在后台播放音乐或者在后台下载就是服务进程。

  • 系统保持它们运行,除非没有足够内存来保证所有的前台进程和可视进程。

第二篇:生命周期


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.1 Service 的生命周期

  • 我们先来看看 Service 的生命周期 的基本流程
  • 一张闻名遐迩的图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.2 开启 Service 的两种方式

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.2.1 startService()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 定义一个类继承 Service

  2. Manifest.xml 文件中配置该 Service

  3. 使用 ContextstartService(intent) 方法开启服务。

  4. 使用 ContextstopService(intent) 方法关闭服务。

  5. 该启动方式,app 杀死、Activity 销毁没有任何影响,服务不会停止销毁。

2.2.2 bindService()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 创建 BindService 服务端,继承 Service 并在类中,创建一个实现 IBinder 接口的实例对象,并提供公共方法给客户端( Activity )调用。

  2. onBinder() 回调方法返回该 Binder 实例。

  3. 在客户端( Activity )中, 从 onServiceConnection() 回调方法参数中接收 Binder ,通过 Binder 对象即可访问 Service 内部的数据。

  4. manifests 中注册 BindService , 在客户端中调用 bindService() 方法开启绑定 Service , 调用 unbindService() 方法注销解绑 Service

  5. 该启动方式依赖于客户端生命周期,当客户端 Activity 销毁时, 没有调用 unbindService() 方法 , Service 也会停止销毁。

2.3 Service 有哪些启动方法,有什么区别,怎样停用 Service

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • Service 的生命周期中,被回调的方法比 Activity 少一些,只有 onCreate , onStart , onDestroy , onBindonUnbind

  • 通常有两种方式启动一个 Service , 他们对 Service 生命周期的影响是不一样的。

2.3.1 通过 startService

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • Service 会经历 onCreateonStart ,然后处于运行状态,stopService 的时候调用 onDestroy 方法。

如果是调用者自己直接退出而没有调用 stopService 的话,Service 会一直在后台运行。

2.3.2 通过 bindService

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Service 会运行 onCreate ,然后是调用 onBind , 这个时候调用者和 Service 绑定在一起。调用者退出了,Srevice 就会调用 onUnbind -> onDestroyed 方法。

所谓绑定在一起就共存亡了。调用者也可以通过调用 unbindService 方法来停止服务,这时候 Srevice 就会调用 onUnbind -> onDestroyed 方法。

2.3.3 需要注意的是如果这几个方法交织在一起的话,会出现什么情况呢?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 一个原则是 ServiceonCreate 的方法只会被调用一次,就是你无论多少次的 startServicebindServiceService 只被创建一次。

  2. 如果先是 bind 了,那么 start 的时候就直接运行 ServiceonStart 方法,如果先是 start ,那么 bind 的时候就直接运行 onBind 方法。

  3. 如果 service 运行期间调用了 bindService ,这时候再调用 stopService 的话,service 是不会调用 onDestroy 方法的,servicestop 不掉了,只能调用 UnbindService , service 就会被销毁

  4. 如果一个 service 通过 startServicestart 之后,多次调用 startService 的话,service 会多次调 用 onStart 方法。多次调用 stopService 的话,service 只会调用一次 onDestroyed 方法。

  5. 如果一个 service 通过 bindServicestart 之后,多次调用 bindService 的话,service 只会调用一次 onBind 方法。多次调用 unbindService 的话会抛出异常。

第三篇:Service 与 Thread


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.1 Service 和 Thread 的区别

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.1.1 首先第一点定义上

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. thread 是程序执行的最小单元,他是分配 cpu 的基本单位安卓系统中,我们常说的主线程,UI 线程,也是线程的一种。当然,线程里面还可以执行一些耗时的异步操作。
  2. service 大家记住,它是安卓中的一种特殊机制,service 是运行在主线程当中的,所以说它不能做耗时操作,它是由系统进程托管,其实 service 也是一种轻量级的 IPC 通信,因为 activity 可以和 service 绑定,可以和 service 进行数据通信。
  3. 而且有一种情况,activityservice 是处于不同的进程当中,所以说它们之间的数据通信,要通过 IPC 进程间通信的机制来进行操作。
3.1.2 第二点是在实际开发的过程当中

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 在安卓系统当中,线程一般指的是工作线程,就是后台线程,做一些耗时操作的线程,而主线程是一种特殊的线程,它只是负责处理一些 UI 线程的绘制,UI 线程里面绝对不能做耗时操作,这里是最基本最重要的一点。(这是 Thread 在实际开发过程当中的应用)
  2. service 是安卓当中,四大组件之一,一般情况下也是运行在主线程当中,因此 service 也是不可以做耗时操作的,否则系统会报 ANR 异常( ANR 全称:Application Not Responding ),就是程序无法做出响应。
  3. 如果一定要在 service 里面进行耗时操作,一定要记得开启单独的线程去做。
3.1.3 第三点是应用场景上

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 当你需要执行耗时的网络,或者这种文件数据的查询,以及其它阻塞 UI 线程的时候,都应该使用工作线程,也就是开启一个子线程的方式。
  2. 这样才能保证 UI 线程不被占用,而影响用户体验。
  3. service 来说,我们经常需要长时间在后台运行,而且不需要进行交互的情况下才会使用到服务,比如说,我们在后台播放音乐,开启天气预报的统计,还有一些数据的统计等等。

3.2 为什么要用 Service 而不是 Thread

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • Thread 的运行是独立于 Activity 的,也就是当一个 Activityfinish 之后,如果没有主动停止 Thread 或者 Thread 中的 run 没有执行完毕时那么这个线程会一直执行下去。
  • 因此这里会出现一个问题:当 Activityfinish 之后,你不再持有该 Thread 的引用。
  • 另一方面,你没有办法在不同的 Activity 中对同一 Thread 进行控制。

3.3 Service 里面是否能执行耗时的操作

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • service 里面不能执行耗时的操作(网络请求,拷贝数据库,大文件 )

  • Service 不是独立的进程,也不是独立的线程,它是依赖于应用程序的主线程的,也就是说,在更多时候不建议在 Service 中编写耗时的逻辑和操作(比如:网络请求,拷贝数据库,大文件),否则会引起 ANR

  • 如果想在服务中执行耗时的任务。有以下解决方案:

  1. service 中开启一个子线程

new Thread(){}.start();

  1. 可以使用 IntentService 异步管理服务( 有关 IntentService 的内容在后文中给出 )

3.4 Service 是否在 main thread 中执行

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 默认情况, 如果没有显示的指 service 所运行的进程, Serviceactivity 是运 行在当前 app 所在进程的 main thread ( UI 主线程)里面。
  • ServiceActivity 在同一个线程,对于同一 app 来说默认情况下是在同一个线程中的 main Thread ( UI Thread )
  • 特殊情况 ,可以在清单文件配置 service 执行所在的进程 ,让 service 在另 外的进程中执行 Service 不死之身

注:如果是在 application 里创建的 Thread :这个 Thread 的生命周期就跟 app 生命周期一致了,不同 activity 也可操作它,这时 service 和这个 Thread 就很相似了(前提是这个 service 只提供给自身 app 使用,第三方 app 不能访问)

3.4.1 在 onStartCommand 方法中将 flag 设置为 START_STICKY ;

return Service.START_STICKY;

3.4.2 在 xml 中设置了 android:priority

<service android:name=“.MyService”
android:priority=“2147483647”

3.4.3 在 onStartCommand 方法中设置为前台进程

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Notification notification = new Notification(R.mipmap.ic_launcher, “服务正在运行”,System.currentTimeMillis());
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,notificationIntent,0);
RemoteViews remoteView = new RemoteViews(this.getPackageName(),R.layout.notification);
remoteView.setImageViewResource(R.id.image, R.mipmap.ic_launcher);
remoteView.setTextViewText(R.id.text , “Hello,this message is in a custom expanded view”);
notification.contentView = remoteView;
notification.contentIntent = pendingIntent;
startForeground(1, notification);
return Service.START_STICKY;
}

3.4.4 在 onDestroy 方法中重启 service

@Override
public void onDestroy() {
super.onDestroy();
startService(new Intent(this, MyService.class));
}

3.4.5 用 AlarmManager.setRepeating(…) 方法循环发送闹钟广播, 接收的时候调用 serviceonstart 方法

Intent intent = new Intent(MainActivity.this,MyAlarmReciver.class);
PendingIntent sender = PendingIntent.getBroadcast( MainActivity.this, 0, intent, 0);

// We want the alarm to go off 10 seconds from now.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 1);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
//重复闹钟
/**

  • @param type
  • @param triggerAtMillis t 闹钟的第一次执行时间,以毫秒为单位
  • go off, using the appropriate clock (depending on the alarm type).
  • @param intervalMillis 表示两次闹钟执行的间隔时间,也是以毫秒为单位
  • of the alarm.
  • @param operation 绑定了闹钟的执行动作,比如发送一个广播、给出提示等等
    */
    am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 2 * 1000, sender);
3.4.6 目前市场面的很多三方的消息推送 SDK 唤醒 APP , 例如 Jpush

PS: 以上这些方法并不代表着你的 Service 就永生不死了,只能说是提高了进程的优先级。迄今为止我没有发现能够通过常规方法达到流氓需求 (通过长按 home 键清除都清除不掉) 的方法,目前所有方法都是指通过 Android 的内存回收机制和普通的第三方内存清除等手段后仍然保持运行的方法,有些手机厂商把这些知名的 app 放入了自己的白名单中,保证了进程不死来提高用户体验(如微信、QQ 、陌陌都在小米的白名单中)。如果从白名单中移除,他们终究还是和普通 app 一样躲避不了被杀的命运。

第四篇:IntentService


  • 作为一个老司机,如果连 Interservice 都没听说过,那就有点那个啥了

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4.1 什么是 IntentService

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • IntentServiceService 的子类,比普通的 Service 增加了额外的功能。

  • 我们常用的 Service 存在两个问题:

  1. Service 不会专门启动一条单独的进程,Service 与它所在应用位于同一个进程中

  2. Service 也不是专门一条新线程,因此不应该在 Service 中直接处理耗时的任务

4.2 IntentService 的特征

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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

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

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

  • ServiceonBind() 提供默认实现,返回 null

  • ServiceonStartCommand 提供默认实现,将请求 Intent 添加到队列中

4.3 Service 和 IntentService 区别

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4.3.1 Service 是用于后台服务的

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 当应用程序被挂到后台的时候,为了保证应用某些组件仍然可以工作而引入了 Service 这个概念
  2. 那么这里面要强调的是:Service 不是独立的进程,也不是独立的线程,它是依赖于应用程序的主线程的,也就是说,在更多时候不建议在 Service 中编写耗时的逻辑和操作,否则会引起 ANR

也就是,service 里面不可以进行耗时的操作。虽然在后台服务。但是也是在主线程里面。

4.3.2 当我们编写的耗时逻辑,不得不被 service 来管理的时候,就需要引入 IntentService

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. IntentService 是继承 Service 的,那么它包含了 Service 的全部特性,当然也包含 service 的生命周期。
  2. 那么与 service 不同的是,IntentService 在执行 onCreate 操作的时候,内部开了一个线程,去你执行你的耗时操作。
4.3.3 使用:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 重写 protected abstract void onHandleIntent(Intent intent)
4.3.4 IntentService 是一个通过 Context.startService(Intent) 启动可以处理异步请求的 Service

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 使用时你只需要继承 IntentService 和重写其中的 onHandleIntent(Intent) 方法接收一个 Intent 对象 , 在适当的时候会停止自己 ( 一般在工作完成的时候 ) 。
  2. 所有的请求的处理都在一个工作线程中完成 , 它们会交替执行 ( 但不会阻塞主线程的执行 ) ,一次只能执行一个请求。
4.3.5 是一个基于消息的服务

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 每次启动该服务并不是马上处理你的工作,而是首先会创建对应的 LooperHandler 并且在 MessageQueue 中添加的附带客户 IntentMessage 对象。
  2. Looper 发现有 Message 的时候接着得到 Intent 对象通过在 onHandleIntent((Intent)msg.obj) 中调用你的处理程序,处理完后即会停止自己的服务。
  3. 意思是 Intent 的生命周期跟你的处理的任务是一致的,所以这个类用下载任务中非常好,下载任务结束后服务自身就会结束退出。
4.3.6 总结 IntentService 的特征有:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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

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

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

第五篇:Service 与 Activity


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5.1 Activity 怎么和 Service 绑定,怎么在 Activity 中启动对应的 Service

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • Activity 通过 bindService(Intent service, ServiceConnection conn, int flags)Service 进行绑定,当绑定成功的时候 Service 会将代理对象通过回调的形式传给 conn ,这样我们就拿到了 Service 提供的服务代理对象。

  • Activity 中可以通过 startServicebindService 方法启动 Service。一般情况下如果想获取 Service 的服务对象那么肯定需要通过 bindService() 方法,比如音乐播放器,第三方支付等。

  • 如果仅仅只是为了开启一个后台任务那么可以使用 startService() 方法。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

总结

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的Android开发中高级必知必会核心笔记,共计2968页PDF、58w字,囊括Android开发648个知识点,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。

虽然面试失败了,但我也不会放弃入职字节跳动的决心的!建议大家面试之前都要有充分的准备,顺顺利利的拿到自己心仪的offer。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。

[外链图片转存中…(img-qeIEjZV8-1713057927419)]

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。

虽然面试失败了,但我也不会放弃入职字节跳动的决心的!建议大家面试之前都要有充分的准备,顺顺利利的拿到自己心仪的offer。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/679661
推荐阅读
相关标签
  

闽ICP备14008679号