OnActivityResult Con launchMode = "singleTask"?
Cuando intenta startActivityForResult
para la Activity
que tiene launchMode="singleTask"
; No devolverá ningún valor con onActivityResult
y cuando establezca launchMode="standard"
; Todo funciona bien, pero los requisitos del sistema dice que esta Activity
debe ser singleTask
, ¿hay singleTask
manera de resolver esto?
- Método de actividad de llamada desde dentro de un fragmento
- Enviar datos del servicio a la actividad Android
- GetRunningAppProcesses () devuelve los procesos que fueron destruidos
- Android.app.Application no se puede convertir en android.app.Activity
- ¿Por qué la función no obtiene datos de php en android?
- ¿Cómo puedo configurar la actividad del Lanzador mediante programación en android?
- Proper onDestroy () / Cómo evitar fugas de memoria
- La aplicación se bloquea cuando se selecciona Modo de liberación pero en modo de depuración funciona perfectamente
- ¿Cómo se crean Fragmentos de preferencias y preferencias en Android?
- Adaptador de matriz de Android con ArrayList y ListView no se actualizan cuando se cambia el arraylist
- Calendario de Android: el resultado de onActivityResult es siempre 0
- Color de fondo ondulado de Android
- Java.lang.IllegalStateException: Fragmento no adjunto a la actividad
Los documentos de la startActivityForResult
dicen:
For example, if the activity you are launching uses the singleTask launch mode, it will not run in your task and thus you will immediately receive a cancel result.
Parece que no hay manera de evitar esto.
Si usted es el desarrollador de Actividad llamada, entonces usted puede tener que enviar una emisión cuando algún resultado está disponible. La actividad que llama puede entonces listar a estas transmisiones.
La respuesta se muestra en la función startActivityUncheckedLocked
de la clase ActivityStackSupervisor
. Antes de Android 5.x, al iniciar una actividad, comprobará launchMode primero y agregará FLAG_ACTIVITY_NEW_TASK
a launchFlags si launchMode es singleTask o singleInstance. Si el launchFlags de la actividad contiene FLAG_ACTIVITY_NEW_TASK
, devolverá una cancelación inmediatamente y dejará que la nueva tarea continúe iniciada de forma normal sin una dependencia de su originador.
if (sourceRecord == null) { // This activity is not being started from another... in this // case we -always- start a new task. if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { Slog.w(TAG, "startActivity called from non-Activity context; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; } } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { // The original activity who is starting us is running as a single // instance... this new activity it is starting must go on its // own task. launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { // The activity being started is a single instance... it always // gets launched into its own task. launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; } // ...... if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { // For whatever reason this activity is being launched into a new // task... yet the caller has requested a result back. Well, that // is pretty messed up, so instead immediately send back a cancel // and let the new task continue launched as normal without a // dependency on its originator. Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, r.requestCode, Activity.RESULT_CANCELED, null); r.resultTo = null; }
Pero en Android 5.x, esto fue cambiado como golpe:
final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP; final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE; final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK; int launchFlags = intent.getFlags(); if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && (launchSingleInstance || launchSingleTask)) { // We have a conflict between the Intent and the Activity manifest, manifest wins. Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " + "\"singleInstance\" or \"singleTask\""); launchFlags &= ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); } else { switch (r.info.documentLaunchMode) { case ActivityInfo.DOCUMENT_LAUNCH_NONE: break; case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING: launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; break; case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS: launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; break; case ActivityInfo.DOCUMENT_LAUNCH_NEVER: launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK; break; } } final boolean launchTaskBehind = r.mLaunchTaskBehind && !launchSingleTask && !launchSingleInstance && (launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0; if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { // For whatever reason this activity is being launched into a new // task... yet the caller has requested a result back. Well, that // is pretty messed up, so instead immediately send back a cancel // and let the new task continue launched as normal without a // dependency on its originator. Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, r.requestCode, Activity.RESULT_CANCELED, null); r.resultTo = null; }
Es por eso que onActivityResult
funciona en Android 5.x incluso se establece launchMode a singleTask
o singleInstance
.
Qué dice @Peter Knego
más
Parece estar funcionando en 5.1, no en 4.4.4
Lo que significa que onActivityResult incendios
Simplemente usé EventBus para enviar eventos a la actividad del llamador, Como sabes que registramos y desregistramos la actividad en el EventBus
en métodos onStart
como onStart
y onStop
, ya que la actividad del llamador después de invocar startActivityForResult
no está visible, la actividad pierde el evento así que tenemos que Publicar los eventos como pegajoso y en el método onStart
comprobar si no se consume y luego tomarlo como un resultado válido.
IBaseEvent.java:
public interface IBaseEvent { boolean isConsumed(); void consume(); Object getData(); }
Event.java:
public class Event implements IBaseEvent { private boolean isConsumed = false; private Object data; public Event(Object data) { isConsumed = false; this.data = data; } @Override public boolean isConsumed() { return isConsumed; } @Override public void consume() { isConsumed = true; } @Override public Object getData() { return data; } }
En la segunda actividad publicar un evento:
EventBus.getDefault().postSicky(new Event(someObject)); finish();
Luego, en la primera (actividad del llamante), añada estas líneas:
@Override protected void onStart() { super.onStart(); EventBus.getDefault().register(this); Event event = EventBus.getDefault().getStickyEvent(Event.class); if (event != null) { if (event.isConsumed()) { EventBus.getDefault().removeStickyEvent(event); } else { EventBus.getDefault().postSticky(event); } } } @Override protected void onStop() { super.onStop(); EventBus.getDefault().unregister(this); } @Subscribe(threadMode = ThreadMode.MAIN) public void onEventHandle(Event event) { //do something ... //and finally consume the event to make it invalid event.consume(); }
De esta manera no perderás ningún evento, espero que ayude.
Sé que esto es bastante tarde, pero puedes tener un efecto OnActivityResult en el método onNewIntent () porque esta es tu actividad singleTask.
- Windows 7 64bit android AVD inicio error: No se pudo asignar memoria: 8
- ¿Por qué debo usar Spring Android?