下面列出了android.app.Service#START_REDELIVER_INTENT 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null && AlarmSyncScheduler.ACTION_SYNC.equals(intent.getAction())) {
final String syncId = intent.getData()
.getFragment();
final Sync sync = storage.get(syncId);
final boolean reschedule = intent.getBooleanExtra(AlarmSyncScheduler.EXTRA_RESCHEDULE, false);
if (sync != null) {
sync.execute()
.doOnTerminate(() -> {
if (reschedule) {
scheduler.reschedule(sync);
}
stopSelf(startId);
})
.subscribe(() -> {
}, throwable -> crashReport.log(throwable));
} else {
scheduler.cancel(syncId);
}
}
return Service.START_REDELIVER_INTENT;
}
/**
* Executes an explicit command.
*
* This is the entry point for arbitrary commands that are executed upon reception of certain
* events that should be executed on the context of this service. The supported commands are:
* - Check last update time and possibly schedule an update of the data for later.
* This is triggered every day, upon reception of the DATE_CHANGED_INTENT_ACTION broadcast.
* - Update data NOW.
* This is normally received upon trigger of the scheduled update.
* - Handle a finished download.
* This executes the actions that must be taken after a file (metadata or dictionary data
* has been downloaded (or failed to download).
* The commands that can be spun an another thread will be executed serially, in order, on
* a worker thread that is created on demand and terminates after a short while if there isn't
* any work left to do.
*/
@Override
public synchronized int onStartCommand(final Intent intent, final int flags,
final int startId) {
final DictionaryService self = this;
if (SHOW_DOWNLOAD_TOAST_INTENT_ACTION.equals(intent.getAction())) {
final String localeString = intent.getStringExtra(LOCALE_INTENT_ARGUMENT);
if (localeString == null) {
Log.e(TAG, "Received " + intent.getAction() + " without locale; skipped");
} else {
// This is a UI action, it can't be run in another thread
showStartDownloadingToast(
this, LocaleUtils.constructLocaleFromString(localeString));
}
} else {
// If it's a command that does not require UI, arrange for the work to be done on a
// separate thread, so that we can return right away. The executor will spawn a thread
// if necessary, or reuse a thread that has become idle as appropriate.
// DATE_CHANGED or UPDATE_NOW are examples of commands that can be done on another
// thread.
mExecutor.submit(new Runnable() {
@Override
public void run() {
dispatchBroadcast(self, intent);
// Since calls to onStartCommand are serialized, the submissions to the executor
// are serialized. That means we are guaranteed to call the stopSelfResult()
// in the same order that we got them, so we don't need to take care of the
// order.
stopSelfResult(startId);
}
});
}
return Service.START_REDELIVER_INTENT;
}
/**
* Executes an explicit command.
*
* This is the entry point for arbitrary commands that are executed upon reception of certain
* events that should be executed on the context of this service. The supported commands are:
* - Check last update time and possibly schedule an update of the data for later.
* This is triggered every day, upon reception of the DATE_CHANGED_INTENT_ACTION broadcast.
* - Update data NOW.
* This is normally received upon trigger of the scheduled update.
* - Handle a finished download.
* This executes the actions that must be taken after a file (metadata or dictionary data
* has been downloaded (or failed to download).
* The commands that can be spun an another thread will be executed serially, in order, on
* a worker thread that is created on demand and terminates after a short while if there isn't
* any work left to do.
*/
@Override
public synchronized int onStartCommand(final Intent intent, final int flags,
final int startId) {
final DictionaryService self = this;
if (SHOW_DOWNLOAD_TOAST_INTENT_ACTION.equals(intent.getAction())) {
final String localeString = intent.getStringExtra(LOCALE_INTENT_ARGUMENT);
if (localeString == null) {
Log.e(TAG, "Received " + intent.getAction() + " without locale; skipped");
} else {
// This is a UI action, it can't be run in another thread
showStartDownloadingToast(
this, LocaleUtils.constructLocaleFromString(localeString));
}
} else {
// If it's a command that does not require UI, arrange for the work to be done on a
// separate thread, so that we can return right away. The executor will spawn a thread
// if necessary, or reuse a thread that has become idle as appropriate.
// DATE_CHANGED or UPDATE_NOW are examples of commands that can be done on another
// thread.
mExecutor.submit(new Runnable() {
@Override
public void run() {
dispatchBroadcast(self, intent);
// Since calls to onStartCommand are serialized, the submissions to the executor
// are serialized. That means we are guaranteed to call the stopSelfResult()
// in the same order that we got them, so we don't need to take care of the
// order.
stopSelfResult(startId);
}
});
}
return Service.START_REDELIVER_INTENT;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String song = intent.getStringExtra(MainActivity.EXTRA_SONG);
Message message = Message.obtain();
message.obj = song;
message.arg1 = startId;
mHandler.sendMessage(message);
return Service.START_REDELIVER_INTENT;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
LOGD(TAG, "onStartCommand");
if (null != intent) {
String action = intent.getAction();
if (ACTION_TOGGLE_PLAYBACK.equals(action) && mIsIcsOrAbove) {
LOGD(TAG, "onStartCommand(): Action: ACTION_TOGGLE_PLAYBACK");
togglePlayback();
} else if (ACTION_STOP.equals(action) && mIsIcsOrAbove) {
LOGD(TAG, "onStartCommand(): Action: ACTION_STOP");
stopApplication();
} else if (ACTION_VISIBILITY.equals(action)) {
mVisible = intent.getBooleanExtra("visible", false);
LOGD(TAG, "onStartCommand(): Action: ACTION_VISIBILITY " + mVisible);
if (mVisible && null != mNotification) {
startForeground(NOTIFICATION_ID, mNotification);
mCastManager.setContext(this);
} else {
stopForeground(true);
}
} else {
LOGD(TAG, "onStartCommand(): Action: none");
}
} else {
LOGD(TAG, "onStartCommand(): Intent was null");
}
return Service.START_REDELIVER_INTENT;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if (AppConfig.DEBUG)
Log.d(TAG, "OnStartCommand called");
final int keycode = intent.getIntExtra(MediaButtonReceiver.EXTRA_KEYCODE, -1);
final Playable playable = intent.getParcelableExtra(EXTRA_PLAYABLE);
if (keycode == -1 && playable == null) {
Log.e(TAG, "PlaybackService was started with no arguments");
stopSelf();
}
if ((flags & Service.START_FLAG_REDELIVERY) != 0) {
if (AppConfig.DEBUG) Log.d(TAG, "onStartCommand is a redelivered intent, calling stopForeground now.");
stopForeground(true);
} else {
if (keycode != -1) {
if (AppConfig.DEBUG)
Log.d(TAG, "Received media button event");
handleKeycode(keycode);
} else {
started = true;
boolean stream = intent.getBooleanExtra(EXTRA_SHOULD_STREAM,
true);
boolean startWhenPrepared = intent.getBooleanExtra(EXTRA_START_WHEN_PREPARED, false);
boolean prepareImmediately = intent.getBooleanExtra(EXTRA_PREPARE_IMMEDIATELY, false);
sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD, 0);
mediaPlayer.playMediaObject(playable, stream, startWhenPrepared, prepareImmediately);
}
}
return Service.START_REDELIVER_INTENT;
}
/**
* Executes an explicit command.
*
* This is the entry point for arbitrary commands that are executed upon reception of certain
* events that should be executed on the context of this service. The supported commands are:
* - Check last update time and possibly schedule an update of the data for later.
* This is triggered every day, upon reception of the DATE_CHANGED_INTENT_ACTION broadcast.
* - Update data NOW.
* This is normally received upon trigger of the scheduled update.
* - Handle a finished download.
* This executes the actions that must be taken after a file (metadata or dictionary data
* has been downloaded (or failed to download).
* The commands that can be spun an another thread will be executed serially, in order, on
* a worker thread that is created on demand and terminates after a short while if there isn't
* any work left to do.
*/
@Override
public synchronized int onStartCommand(final Intent intent, final int flags,
final int startId) {
final DictionaryService self = this;
if (SHOW_DOWNLOAD_TOAST_INTENT_ACTION.equals(intent.getAction())) {
final String localeString = intent.getStringExtra(LOCALE_INTENT_ARGUMENT);
if (localeString == null) {
Log.e(TAG, "Received " + intent.getAction() + " without locale; skipped");
} else {
// This is a UI action, it can't be run in another thread
showStartDownloadingToast(
this, LocaleUtils.constructLocaleFromString(localeString));
}
} else {
// If it's a command that does not require UI, arrange for the work to be done on a
// separate thread, so that we can return right away. The executor will spawn a thread
// if necessary, or reuse a thread that has become idle as appropriate.
// DATE_CHANGED or UPDATE_NOW are examples of commands that can be done on another
// thread.
mExecutor.submit(new Runnable() {
@Override
public void run() {
dispatchBroadcast(self, intent);
// Since calls to onStartCommand are serialized, the submissions to the executor
// are serialized. That means we are guaranteed to call the stopSelfResult()
// in the same order that we got them, so we don't need to take care of the
// order.
stopSelfResult(startId);
}
});
}
return Service.START_REDELIVER_INTENT;
}
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
@SuppressLint("InlinedApi")
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return Service.START_REDELIVER_INTENT;
}
@Override
@SuppressLint("InlinedApi")
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return Service.START_REDELIVER_INTENT;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, Service.START_REDELIVER_INTENT, startId);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Timber.d("starting MediaListenerService for file observing");
if (observer == null)
startWatching();
return Service.START_REDELIVER_INTENT;
}