从系统看Service的重启

onStartCommand返回值的区别

@IntDef(flag = false, prefix = { "START_" }, value = {
        START_STICKY_COMPATIBILITY,
        START_STICKY,
        START_NOT_STICKY,
        START_REDELIVER_INTENT,
})

START_STICKY_COMPATIBILITY
Service被杀死后会重启(执行了onCreate方法),但是onStartCommand方法没有被执行。

 D/MyService: onCreate
 D/MyService: onStartCommand intent=Intent { cmp=com.example.myapplication/.MyService (has extras) } startId=1
 D/MyService: startResult= 0 //START_STICKY_COMPATIBILITY
system_process W/ActivityManager: Scheduling restart of crashed service com.example.myapplication/.MyService in 1000ms for start-requested
system_process D/Boost: hostingType=service, hostingName={com.example.myapplication/com.example.myapplication.MyService}, callerPackage=com.example.myapplication, isSystem=false, isBoostNeeded=false.
system_process I/ActivityManager: Start proc 7675:com.example.myapplication/u0a270 for service {com.example.myapplication/com.example.myapplication.MyService} caller=com.example.myapplication
D/MyService: onCreate

START_STICKY
进程被杀后Service会被重启,执行onCreate和onStartCommand,重启后的Intent为null

MyService: onCreate
D/MyService: onStartCommand intent=Intent { cmp=com.example.myapplication/.MyService (has extras) } startId=1
D/MyService: startResult= 1 // START_STICKY
system_process W/ActivityManager: Scheduling restart of crashed service com.example.myapplication/.MyService in 1000ms for start-requested
system_process D/Boost: hostingType=service, hostingName={com.example.myapplication/com.example.myapplication.MyService}, callerPackage=com.example.myapplication, isSystem=false, isBoostNeeded=false.
system_process I/ActivityManager: Start proc 4522:com.example.myapplication/u0a270 for service {com.example.myapplication/com.example.myapplication.MyService} caller=com.example.myapplication
 D/MyService: onCreate
D/MyService: onStartCommand intent=null startId=2 // startID不一致,代表不是同一个实例,intent为null
D/MyService: startResult= 1

START_NOT_STICKY
进程被杀后Service不会被重启

D/MyService: onStartCommand intent=Intent { cmp=com.example.myapplication/.MyService (has extras) } startId=1
D/MyService: startResult= 2  //START_NOT_STICKY

START_REDELIVER_INTENT
Service被杀死后会重启(执行了onCreate方法),并且onStartCommand方法会执行。从startId可以看出两个Service对象是同一个,并且onStartCommand方法中的intent和前一个intent值是一致的。

D/MyService: onCreate
D/MyService: onStartCommand intent=Intent { cmp=com.example.myapplication/.MyService (has extras) } startId=1
D/MyService: startResult= 3
ActivityManager: Scheduling restart of crashed service com.example.myapplication/.MyService in 17938ms for start-requested
system_process D/Boost: hostingType=service, hostingName={com.example.myapplication/com.example.myapplication.MyService}, callerPackage=com.example.myapplication, isSystem=false, isBoostNeeded=false.
system_process I/ActivityManager: Start proc 6307:com.example.myapplication/u0a270 for service {com.example.myapplication/com.example.myapplication.MyService} caller=com.example.myapplication
 D/MyService: onCreate
 D/MyService: onStartCommand intent=Intent { cmp=com.example.myapplication/.MyService (has extras) } startId=1
 D/MyService: startResult= 3

RestartService的流程

在这里插入图片描述
1、无须restart Service,直接bringDown的情况

  • 非persistent进程crash次数达到16次
  • 不允许自启Service
  • Service的userId不在运行中
final void killServicesLocked(ProcessRecord app, boolean allowRestart) {
   ......
    for (int i=app.services.size()-1; i>=0; i--) {
        ServiceRecord sr = app.services.valueAt(i);
 
       ......
        // Any services running in the application may need to be placed
        // back in the pending list.
        if (allowRestart && sr.crashCount >= mAm.mConstants.BOUND_SERVICE_MAX_CRASH_RETRY
                && (sr.serviceInfo.applicationInfo.flags
                    &ApplicationInfo.FLAG_PERSISTENT) == 0) {
            // 若进程crash次数大于等于16次,且为非persistent进程,则直接bringDown Service
            bringDownServiceLocked(sr);
        } else if (!allowRestart|| !mAm.mUserController.isUserRunning(sr.userId, 0)) {
            // 若不允许重启或当前userId不在运行,则直接bringDown Service
            bringDownServiceLocked(sr);
        } else {
            // 直接计划Service的重启,成功返回true,否则返回false
            boolean canceled = scheduleServiceRestartLocked(sr, true);
 
            // start方式启动,且以下两种满足一种
            // 1.app的onStartCommand方法返回值不是sticky的
            // 2.计划restart 被取消
            // 且Service没有pending start ,会将Service的startRequested置为false,这种情况会导致isServiceNeededLocked为false,restartService失败
            // stopIfKilled 由onStartCommand返回值决定
            if (sr.startRequested && (sr.stopIfKilled || canceled)) {
                if (sr.pendingStarts.size() == 0) {
                    sr.startRequested = false;
                    ......
                    // 如果Service没有AutoCreate相关的Connections,则会直接bringDown Service
                    if (!sr.hasAutoCreateConnections()) {
                        // Whoops, no reason to restart!
                        bringDownServiceLocked(sr);
                    }
                }
            }
        }
    }
}

2、restartService被取消的情况
可以通过调用unscheduleServiceRestartLocked方法来取消restart service,取消

  • bringDownServiceLocked 在killServicesLocked时会有
  • startServiceLocked
  • bindServiceLocked

3、restartService成功的情况
killServicesLocked时如果条件满足,会通过scheduleServiceRestartLocked去post ServiceRestarter到MainHandler里,当run方法被执行时会去调用performServiceRestartLocked

此时回去再次校验是否需要重启,如下情况可以重启

  • Service有AutoCreate的Connections 非Start方式启动

  • onStartCommand返回值为START_STICKY_COMPATIBILITY或START_STICKY

  • Service的pendingStarts不为空

final void performServiceRestartLocked(ServiceRecord r) {
    // Service会在scheduleServiceRestartLocked方法中添加到mRestartingServices列表中
    if (!mRestartingServices.contains(r)) {
        return;
    }
    if (!isServiceNeededLocked(r, false, false)) {
        Slog.wtf(TAG, "Restarting service that is not needed: " + r);
        return;
    }
    ......
}
private final boolean isServiceNeededLocked(ServiceRecord r, boolean knowConn,
        boolean hasConn) {
    // start方式启动的话得看onStartcommand的返回值以及是否有pending starts,startReuested是有可能为false的。
    if (r.startRequested) {
        return true;
    }
 
    // Is someone still bound to us keeping us running?
    if (!knowConn) {
        hasConn = r.hasAutoCreateConnections();
    }
    if (hasConn) {
        return true;
    }
 
    return false;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值