Android基础之service

本文详细介绍了Android中的Service概念及其启动方式,包括startService和bindService的区别与使用方法,并讲解了IntentService、前台Service的概念及如何防止Service被系统回收。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、service 简述

后台开启 程序退出后仍然可以人为进行操作运行

是一种可以在后台执行长时间运行操作而没有用户界面的应用组件

运行在UI线程不能做耗时操作

二、service与Thread区别

它们之间没有任何关系

Thread 是运行相对独立 程序执行的最小单元 可以通过开启一个子线程来做耗时操作

service运行依托于主线程 不能做耗时操作 否则会报ANR

三、service启动方式startService和bindService

startService
生命周期: onCreate()->onStartCommand()->onDestory()

在第一次启动时调用onCreate 之后调用多次都不会再调onCreate
无论运行startService多少次,只要调用一次stopService或者stopSelf,Service都会停止。

用法:

<1>继承service
<2>在清单文件中注册service
<3>使用startService(intent)启动service
<4>不在使用时,调用stopService/stopSelf来停止服务

onStartCommand方法返回值int 可选值及含义如下:

START_NOT_STICKY:当Service因为内存不足而被系统kill后,接下来未来的某个时间内,即使系统内存足够可用,系统也不会尝试重新创建此Service。除非程序中Client明确再次调用startService(...)启动此Service。

START_STICKY:当Service因为内存不足而被系统kill后,接下来未来的某个时间内,当系统内存足够可用的情况下,系统将会尝试重新创建此Service,一旦创建成功后将回调onStartCommand(...)方法,但其中的Intent将是null,pendingintent除外。

START_REDELIVER_INTENT:与START_STICKY唯一不同的是,回调onStartCommand(...)方法时,其中的Intent将是非空,将是最后一次调用startService(...)中的intent。

START_STICKY_COMPATIBILITY:不常用

注:

1、onStartCommand(…)可以多次被调用,onDestroy()与onCreate()想匹配,当用户强制kill掉进程时,onDestroy()是不会执行的。
2、对于同一类型的Service,Service实例一次永远只存在一个,而不管Client是否是相同的组件,也不管Client是否处于相同的进程中。
3、Service通过startService(…)启动Service后,此时Service的生命周期与Client本身的什么周期是没有任何关系的,只有Client调用stopService(…)或Service本身调用stopSelf(…)才能停止此Service。当然,当用户强制kill掉Service进程或系统因内存不足也可能kill掉此Service。
4、Client A 通过startService(…)启动Service后,可以在其他Client(如Client B、Client C)通过调用stopService(…)结束此Service
5、Client调用stopService(…)时,如果当前Service没有启动,也不会出现任何报错或问题,也就是说,stopService(…)无需做当前Service是否有效的判断
6、startService(Intent serviceIntent),其中的intent既可以是显式Intent,也可以是隐式Intent,当Client与Service同处于一个App时,一般推荐使用显示Intent。当处于不同App时,只能使用隐式Intent。

bindService
生命周期:onCreate()->onBind()->onUnbind()->onDestory()

以bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止。

onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。

通过Service中的Binder对象可以较为方便进行Client-Service通信

使用过程:

1、继承基类Service,并重写onBind(Intent intent)方法,此方法中需要返回具体的Binder对象
  
2、通过bindService方法启动service

3、实现ServiceConnection接口,通过onServiceConnected(ComponentName name, IBinder binder)方法,获取Service端Binder实例;

4、通过获取的Binder实例进行Service端其他公共方法的调用,以完成Client-Service通信;

5、当Client退出时,此时需要调用函数unbindService(),解绑之前已经绑定的Service。

四、IntentService

是一种特殊的service。可用于在后台执行一些耗时的操作,当任务执行完成后会自动停止。由于IntentService是一种服务,这样它的优先级要高于单纯的线程,所以比较适合执行一些高优先级的后台任务

使用:

继承IntentService,实现其的onHandleIntent()方法,在该方法中去做一些耗时操作

它的内部是通过HandleThread和Handle实现的。

1、在onCreate方法中创建HandleThread,使用HandleThread的getLooper方法创建Looper对象,通过该Looper对象创建该线程的Handle。		

2、onStartCommand方法中调用onstart方法

3、onStart方法中发送message将Intent发送给Handle

4、Handle的handleMessage方法中调用onHandleIntent((Intent)msg.obj);执行耗时操作,执行完毕后调用stopSelf自动停止

五、前台Service

由于Service的优先级很低,所以在手机灭屏一段时间后,service很可能就被系统干掉回收了,为了保证service不会被系统回收,我们需要将service设置为前台服务

使用:

1、创建 Build Notification.Builder builder = new Notification.Builder(this);

2、设置 build的信息 

3、获取 notification Notification notification = builder.build();

4、启动前台服务 Service.startForeground(100, notification);

service更新notification 比如:实现实时更新进度条的进度:

1、创建NotificationManager: 
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

2、设置更新的build数据

3、发送通知消息:notificationManager.notify(100,notification);

自定义notification的view

1、创建RemoteViews实例: 
RemoteViews remoteViews = new RemoteViews(this.getPackageName(),R.layout.notification_layout);
// 获取remoteViews(参数一:包名;参数二:布局资源)

2、设置自定义的Notification内容: builder.setCustomContentView(remoteViews);

3、为自定义通知内容上的控件绑定点击事件(使用广播.可以针对不同的控件id创建不同的广播)

    <1> 指定操作意图:
    Intent intentPlay = new Intent(ACTION_PLAY);//设置对应的行为ACTION
    <2> 发送一个广播:
    PendingIntent pIntentPlay = PendingIntent.getBroadcast(this.getApplicationContext(),1, intentPlay, PendingIntent.FLAG_UPDATE_CURRENT);
    <3> 绑定点击事件:
    remoteViews.setOnClickPendingIntent(R.id.iv_pause, pIntentPlay);//(参数一:// 控件id;参数二:对应触发的PendingIntent)

4、监听对应广播

六、保证service不被"杀死"

1、onStartCommand的返回值设置为START_STICKY

2、<intent-filter>设置service优先级

3、设置service为前台service

4、在onDestory方法中发送广播再次启动service或直接启动service
......
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值