1-2 Service基础全记录

[TOC]

1. 什么是Service

Service 是与Activity最为相似的组件,主要区别在于Service没有用户界面。Service是Android中实现程序后台运行解决方案,例如音乐的后台播放功能,消息的推送收取,后台文件的下载等等。它适合不与用户交互但需要执行较长周期的任务。这也是它与Activity的最大区别,它不收用户的操作影响,即使程序切换到后台,或打开其他应用程序,也能正常运行

2.使用场景

  • 后台音乐播放
  • 消息定时推送
  • 后台下载任务
  • 。。。

3. 生命周期

Service生命周期.jpg
方法 说明 补充
onCreate() 创建服务 只会创建一次
onStartCommand(intent: Intent?, flags: Int, startId: Int): Int 无绑定启动服务 多次启动,多次回调调用
返回值决定了服务异常结束情况下的重启操作:1.START_STICKY
2.START_NOT_STICKY
3.START_REDELIVER_INTENT
4.START_STICKY_COMPATIBILITY
5.START_STICKY
onBind(intent: Intent): IBinder 绑定启动服务 多次启动,多次回调调用(前提是调用的Intent不一样,否则不会执行多次)
这里返回的IBinder是服务内部实现并传递给绑定方用于交互的对象
onUnbind(intent: Intent?): Boolean 解绑服务 多次调用会导致崩溃,解绑时会解绑所有已绑定的调用
stopService(Intent name) 停止服务 多次调用只执行一次
onDestroy() 销毁前调用
stopSelf() 停止自身
onRebind(intent: Intent?) 重新绑定 触发步骤:先启动,再绑定,再解绑,再次绑定<br />发生条件:
1. 需要由Activity先startService启动
2. onUnbind时需要返回true
3. 传递的intent需要一致
  • START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
  • START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统将会把它置为started状态,系统不会自动重启该服务,直到startService(Intent intent)方法再次被调用;
  • START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入
  • START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

4. 使用

2.1 Service的简要记录图表

创建与使用


Service创建与使用.png

2.2 无绑定启动

无绑定启动意味着Service与访问者之间无太大关联,同时也意味着它们无法通信或是数据交换,因此Service中执行自有的业务逻辑即可,等待着被销毁或任务结束自行销毁

//启动
var intent=Intent(this@MainActivity,SimpleService::class.java)
startService(intent)
//停止
var intent=Intent(this@MainActivity,SimpleService::class.java) intent.action="android.intent.action.SimpleService"
intent.`package`=this@MainActivity.packageName
stopService(intent)
调用方调用方法 说明 补充
startService(Intent service) 启动服务
stopService(Intent name) 停止服务 多次调用只执行一次

2.3 绑定启动

使用绑定启动时,意味着我们需要与Service进行交互,此时的做法是,在Service中先定义出Binder,在Binder中编写需要的功能,例如后台录音功能startRecord()与stopRecord(),然后通过bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE)实现绑定,serviceConnection就是用来获取绑定成功时返回的binder对象,此时便可以进行交互了

//绑定服务
bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE)
//解绑服务
unbindService(serviceConnection)

var serviceConnection = object : ServiceConnection {
    override fun onServiceDisconnected(p0: ComponentName?) {
        Log.e(TAG,"异常解绑时调用")
    }
override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
        binder = p1 as SimpleService.CountBinder;
        binder.startRecord()
        binder.stopRecord()
        Log.e(TAG,""+binder.count+"")
    }
}


方法 说明 补充
bindService(Intent service, ServiceConnection conn, int flags) 绑定启动服务 conn是服务绑定需要的中间类,通过它来绑定解绑
flags是指明绑定服务时是否自动创建(0-否,Context.BIND_AUTO_CREATE-是)
unbindService(ServiceConnection conn) 解绑服务 多次调用会出现异常
java.lang.IllegalArgumentException: Service not registered
ServiceConnection.onServiceDisconnected(ComponentName var1) 服务异常解绑时会调用该方法 正常解绑时不会触发改方法
ServiceConnection.onServiceConnected(ComponentName var1, IBinder var2) 绑定成功时的回调 var2就可以向下转换为我们需要的binder

5.其他补充

服务实际上每个只会存在一个实例,在整个应用程序范围内都是通用的,绑定多个都可以获取到相同的binder实例

5.1 当Service既被无绑定启动又被绑定启动时,需要执行解绑及停止时才能进入销毁流程

Android系统机制:一个服务只要被启动或者被绑定了之后,就会一直处于运行状态
绑定关系实际上是Service将自己的内部对象binder传递给了调用方,并不会完全将Service的生命周期绑定到调用方,调用方调用unBindService方法实际上是切断了与Service的关联

5.2 错误:*java.lang.IllegalArgumentException: Service Intent must be explicit: Intent {act=android.intent.action.SimpleService }

Android 5.0 (Lollipop) 之后的规定。 不能用包名的方式定义Service Intent, 而要用显性声明
想继续使用隐式意图的话,加上包名信息即可

5.3多次启动或绑定服务时,也只会有一个服务存在,且binder也是同一个

通过设置不同的type实现绑定多个intent.type=""

5.4创建前台服务

与普通的Service类似,唯一不同就是在onCreate中到调用startForeground方法,这样在下拉通知栏中就可以看到该服务

@Override
public void onCreate() {
    super.onCreate();
    Intent intent = new Intent(this,    MainActivity.class);
    PendingIntent pendingIntent =       PendingIntent.getActivity(this, 0, intent, 0);
    Notification notification = new     NotificationCompat.Builder(this)
    .setContentTitle("Foreground")
    .setContentText("前台服务")
    .setSmallIcon(R.mipmap.ic_launcher)
    .setContentIntent(pendingIntent)
    .build();
    startForeground(1,notification);
}

5.5 IntentService

Service不会专门启动一条单独的进程,与所在应用再同一个进程中

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

  • IntentService使用队列来管理请求 Intent
    每当调用方通过Intent请求启动IntentService时,IntentService将该Intent加入队列中,然后开启一条新的worker线程处理该Intent。对于异步的startService请求,IntentService会按次序依次处理队列中的Intent,该线程保证同一时刻只处理一个Intent。

  • IntentService使用新的worker线程处理Intent请求,onHandleIntent(@Nullable Intent intent) 方法中即在子线程中运行
    因此IntentService不好阻塞主线程,自己就可以处理耗时任务

  • 默认实现onBind ,返回null

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

  • 自定义实现

    //同样需要在清单文件中注册
    public class MyIntentService extends IntentService {
        private static final String TAG = "MyIntentService";
    
        public MyIntentService() {
            super("MyIntentService");
        }
        @Override
        protected void onHandleIntent(@Nullable Intent intent) {
            Log.e(TAG, "onHandleIntent: " );
        }
    }
    
  • 执行完任务后自动停止

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容