下面列出了android.app.Service#START_STICKY_COMPATIBILITY 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
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.
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, false, true);
// Don't stop if killed.
r.stopIfKilled = false;
break;
}
case Service.START_NOT_STICKY: {
// We are done with the associated start arguments.
r.findDeliveredStart(startId, false, true);
if (r.getLastStartId() == startId) {
// There is no more work, and this service
// doesn't want to hang around if killed.
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, false);
if (si != null) {
si.deliveryCount = 0;
si.doneExecutingCount++;
// Don't stop if killed.
r.stopIfKilled = true;
}
break;
}
case Service.START_TASK_REMOVED_COMPLETE: {
// Special processing for onTaskRemoved(). Don't
// impact normal onStartCommand() processing.
r.findDeliveredStart(startId, true, true);
break;
}
default:
throw new IllegalArgumentException(
"Unknown service start result: " + res);
}
if (res == Service.START_STICKY_COMPATIBILITY) {
r.callStart = false;
}
} else if (type == ActivityThread.SERVICE_DONE_EXECUTING_STOP) {
// This is the final call from destroying the service... we should
// actually be getting rid of the service at this point. Do some
// validation of its state, and ensure it will be fully removed.
if (!inDestroying) {
// Not sure what else to do with this... if it is not actually in the
// destroying list, we don't need to make sure to remove it from it.
// If the app is null, then it was probably removed because the process died,
// otherwise wtf
if (r.app != null) {
Slog.w(TAG, "Service done with onDestroy, but not inDestroying: "
+ r + ", app=" + r.app);
}
} else if (r.executeNesting != 1) {
Slog.w(TAG, "Service done with onDestroy, but executeNesting="
+ r.executeNesting + ": " + r);
// Fake it to keep from ANR due to orphaned entry.
r.executeNesting = 1;
}
}
final long origId = Binder.clearCallingIdentity();
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
Binder.restoreCallingIdentity(origId);
} else {
Slog.w(TAG, "Done executing unknown service from pid "
+ Binder.getCallingPid());
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (DEBUG) {
Log.d(TAG, "onStartCommand(Intent intent, int flags, int startId) : intent="
+ ((intent == null) ? "null." : intent.toString())
+ "; flags=" + flags + "; startId=" + startId);
}
if (mIActivityManagerProxy == null) {
// 容错,不能支持Service了
return 0;
}
if (intent == null) {
return START_STICKY;
}
// 调用super,返回值用super的
int ret = super.onStartCommand(intent, flags, startId);
// 调用插件的onStartCommand方法
int targetRet = 0;
ComponentName target = getTargetComponent(intent);
if (target == null) {
if (mServices.isEmpty()) {
stopSelf();
}
return ret;
}
// 插件SDK不能支持百度PushService,暂时先屏蔽了。
if (TextUtils.equals(target.getClassName(), "com.baidu.android.pushservice.PushService")) {
return ret;
}
// 获取SR
ServiceRecord sr = mServices.get(target.toString());
if (sr == null) {
sr = loadTarget(intent, target, false);
}
// SR还是空的,可能是load失败了
if (sr == null) {
if (mServices.isEmpty()) {
stopSelf();
}
return ret;
}
// 解决andorid 5.0 service get Serializable extra 找不到class的问题。
intent.setExtrasClassLoader(ProxyEnvironment.getInstance(target.getPackageName()).getDexClassLoader());
targetRet = sr.service.onStartCommand(intent, flags, startId);
// 处理插件返回的ret
switch (targetRet) {
case Service.START_STICKY_COMPATIBILITY:
case Service.START_STICKY: {
sr.stopIfKilled = false;
break;
}
case Service.START_NOT_STICKY: {
if (sr.lastStartId == startId) {
sr.stopIfKilled = true;
}
break;
}
case Service.START_REDELIVER_INTENT: {
sr.lastIntent = new Intent(intent);
sr.stopIfKilled = false;
// 更新Intent
updateServicesToSp();
break;
}
default:
throw new IllegalArgumentException("Unknown service start result: " + targetRet);
}
updateServicesToSp();
return ret;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY_COMPATIBILITY;
}