当Service被异常销毁后,默认都会自动重启,但Service的自动重启是如何实现的尼?下面就来梳理一下Service的自动重启流程。
 无论Service是启动还是绑定成功,都会调用ActiveServicesserviceDoneExecutingLocked方法,来看一下这个方法的实现。

    void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {        boolean inDestroying = mDestroyingServices.contains(r);        if (r != null) {            if (type == ActivityThread.SERVICE_DONE_EXECUTING_START) {                // This is a call from a service start...  take care of                // book-keeping.                //默认调用Service的startCommand这个方法                r.callStart = true;                switch (res) {                    case Service.START_STICKY_COMPATIBILITY:                    case Service.START_STICKY: {                        // We are done with the associated start arguments.                        r.findDeliveredStart(startId, true);                        // Don't stop if killed.                        //被异常kill掉,允许重启该Service                        r.stopIfKilled = false;                        break;                    }                    case Service.START_NOT_STICKY: {                        // We are done with the associated start arguments.                        r.findDeliveredStart(startId, true);                        if (r.getLastStartId() == startId) {                            // There is no more work, and this service                            // doesn't want to hang around if killed.                            //被异常kill掉,不允许重启该Service                            r.stopIfKilled = true;                        }                        break;                    }                    case Service.START_REDELIVER_INTENT: {                        // We'll keep this item until they explicitly                        // call stop for it, but keep track of the fact                        // that it was delivered.                        ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);                        if (si != null) {                            si.deliveryCount = 0;                            si.doneExecutingCount++;                            // Don't stop if killed.                            //被异常kill掉,不允许重启。但后面会依靠deliveredStarts触发重启                            r.C= true;                        }                        break;                    }                    case Service.START_TASK_REMOVED_COMPLETE: {                        // Special processing for onTaskRemoved().  Don't                        // impact normal onStartCommand() processing.                        r.findDeliveredStart(startId, true);                        break;                    }                    default:                        throw new IllegalArgumentException(                                "Unknown service start result: " + res);                }                if (res == Service.START_STICKY_COMPATIBILITY) {                    //当startCommand返回START_STICKY_COMPATIBILITY时则不允许调用startCommand方法                    r.callStart = false;                }            } else if (type == ActivityThread.SERVICE_DONE_EXECUTING_STOP) {                ...            }            ...        } else {            ...        }    }

 当Service启动或绑定成功后就会给当前Service给stopIfKilled这个标志位赋值,该标志位决定当Service被异常kill掉后是否需要重启。
 Service被意外kill后会调用ActiveServiceskillServicesLocked方法,来看看这个方法的实现。

    final void killServicesLocked(ProcessRecord app, boolean allowRestart) {        ...        ServiceMap smap = getServiceMapLocked(app.userId);        // Now do remaining service cleanup.        for (int i=app.services.size()-1; i>=0; i--) {            //拿到Service的信息            ServiceRecord sr = app.services.valueAt(i);            ...            // Any services running in the application may need to be placed            // back in the pending list.            //如果连续两次重启失败就不再重启Service            if (allowRestart && sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags                    &ApplicationInfo.FLAG_PERSISTENT) == 0) {                ...                //不允许重启                bringDownServiceLocked(sr);            } else if (!allowRestart//不允许重启                    || !mAm.mUserController.isUserRunningLocked(sr.userId, 0)) {                //不允许重启                bringDownServiceLocked(sr);            } else {                //尝试重启                boolean canceled = scheduleServiceRestartLocked(sr, true);                //在多次尝试发送失败的命令的极端情况下,也会在这里停止它。                if (sr.startRequested && (sr.stopIfKilled || canceled)) {                    if (sr.pendingStarts.size() == 0) {                        sr.startRequested = false;                        if (sr.tracker != null) {                            sr.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),                                    SystemClock.uptimeMillis());                        }                        if (!sr.hasAutoCreateConnections()) {                            // Whoops, no reason to restart!                            //哎呀,没理由重启!                            bringDownServiceLocked(sr);                        }                    }                }            }        }       //做一些清理操作       ...    }

 从上面代码可以看出,尝试重启的具体实现是在scheduleServiceRestartLocked这个方法里,来看看它的实现。

    private final boolean scheduleServiceRestartLocked(ServiceRecord r, boolean allowCancel) {        boolean canceled = false;        ...        final long now = SystemClock.uptimeMillis();        if ((r.serviceInfo.applicationInfo.flags                &ApplicationInfo.FLAG_PERSISTENT) == 0) {            long minDuration = mAm.mConstants.SERVICE_RESTART_DURATION;            long resetTime = mAm.mConstants.SERVICE_RESET_RUN_DURATION;            // Any delivered but not yet finished starts should be put back            // on the pending list.            final int N = r.deliveredStarts.size();            if (N > 0) {                for (int i=N-1; i>=0; i--) {                    ServiceRecord.StartItem si = r.deliveredStarts.get(i);                    si.removeUriPermissionsLocked();                    if (si.intent == null) {                        // We'll generate this again if needed.                    } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT                            && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {                        //重启的时候,deliveredStarts被pendingStarts替换掉了,这样就能拿到Intent的值                        // 也就说,这个时候START_REDELIVER_INTENT由死转生                        r.pendingStarts.add(0, si);                        long dur = SystemClock.uptimeMillis() - si.deliveredTime;                        //将重启间隔时间拉大,被kill掉次数越多,重启所需要时间越长                        dur *= 2;                        if (minDuration < dur) minDuration = dur;                        if (resetTime < dur) resetTime = dur;                    } else {                        Slog.w(TAG, "Canceling start item " + si.intent + " in service "                                + r.name);                        canceled = true;                    }                }                r.deliveredStarts.clear();            }            //重启次数加1            r.totalRestartCount++;            if (r.restartDelay == 0) {                r.restartCount++;                r.restartDelay = minDuration;            } else {                // If it has been a "reasonably long time" since the service                // was started, then reset our restart duration back to                // the beginning, so we don't infinitely increase the duration                // on a service that just occasionally gets killed (which is                // a normal case, due to process being killed to reclaim memory).                if (now > (r.restartTime+resetTime)) {                    r.restartCount = 1;                    r.restartDelay = minDuration;                } else {                    r.restartDelay *= mAm.mConstants.SERVICE_RESTART_DURATION_FACTOR;                    if (r.restartDelay < minDuration) {                        r.restartDelay = minDuration;                    }                }            }            r.nextRestartTime = now + r.restartDelay;            //两个Service启动至少间隔10秒,这里的意义其实不是很大,主要是为了Service启动失败的情况,如果启动成功,其他要启动的Service会被一并直接重新唤起            boolean repeat;            do {                repeat = false;                final long restartTimeBetween = mAm.mConstants.SERVICE_MIN_RESTART_TIME_BETWEEN;                for (int i=mRestartingServices.size()-1; i>=0; i--) {                    ServiceRecord r2 = mRestartingServices.get(i);                    if (r2 != r && r.nextRestartTime >= (r2.nextRestartTime-restartTimeBetween)                            && r.nextRestartTime < (r2.nextRestartTime+restartTimeBetween)) {                        r.nextRestartTime = r2.nextRestartTime + restartTimeBetween;                        r.restartDelay = r.nextRestartTime - now;                        repeat = true;                        break;                    }                }            } while (repeat);        } else {            // Persistent processes are immediately restarted, so there is no            // reason to hold of on restarting their services.            r.totalRestartCount++;            r.restartCount = 0;            r.restartDelay = 0;            r.nextRestartTime = now;        }        if (!mRestartingServices.contains(r)) {            r.createdFromFg = false;            mRestartingServices.add(r);            r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);        }        cancelForegroundNotificationLocked(r);        mAm.mHandler.removeCallbacks(r.restarter);        //执行Service重启操作,这里的restarter就是一个ServiceRestarter对象,在ServiceRecord创建时添加进去的        mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;        ...        return canceled;    }    private class ServiceRestarter implements Runnable {        private ServiceRecord mService;        void setService(ServiceRecord service) {            mService = service;        }        public void run() {            synchronized(mAm) {                //开始重启                performServiceRestartLocked(mService);            }        }    }    final void performServiceRestartLocked(ServiceRecord r) {        ...        try {            bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true, false);        } catch (TransactionTooLargeException e) {            ...        }    }

 最后就在ServiceRestarter执行重新创建Service操作,在run方法里调用了performServiceRestartLocked来进行重启,而performServiceRestartLocked里直接调用了bringUpServiceLocked这个方法,这个就是重新创建Service的方法,关于这个方法的详细实现可以去阅读Android源码之Service启动流程这篇文章。

Android的服务(Service)(二)Service的自动重启问题
Android Service重启恢复(Service进程重启)原理解析

更多相关文章

  1. Android入门(7):活动的启动模式
  2. Android(安卓)RecycleView(二)——添加分割线
  3. Android中WebView与Javascript的交互
  4. Android的JS调用Java代码或使用了Javascript相关技术,如何混淆
  5. Android疑问1——Handler的removeCallbacks方法无效?(已经明白了)
  6. Android(安卓)Fatal signal 6 (SIGABRT) at 0x0000271d (code=-6
  7. 直播平台软件开发Android(安卓)Activity横竖屏切换生命周期详解
  8. Android(安卓)ADB命令大全(通过ADB命令查看wifi密码、MAC地址、
  9. 运行时动态注销在AndroidManifest.xml声明的BroadcastReceiver,En

随机推荐

  1. Dialog-普通对话框-列表对话框
  2. Android与JS交互---内嵌框架iframe
  3. Android Retrofit 图片上传的最简单和明
  4. Android 监听屏幕熄屏亮屏和主动唤醒屏幕
  5. android显示自定义view
  6. 利用Java反射机制-访问Android隐藏API
  7. android studio 启动失败(Failed to load
  8. Android 三星128G SD卡格式化为内部存储
  9. android内存管理工具类
  10. 从xml中改变checkBox大小和形状