Nano Hash - криптовалюты, майнинг, программирование

onActivityResult С launchMode=singleTask?

Когда вы пытаетесь startActivityForResult для Activity, у которого есть launchMode="singleTask"; он не вернет никаких значений с onActivityResult, и когда вы установите launchMode="standard"; все работает нормально, но в системных требованиях написано, что это Activity должно быть singleTask, можно ли как-то это решить?


Ответы:


1

Документы startActivityForResult говорят:

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.

Кажется, нет никакого способа обойти это.

Если вы являетесь разработчиком под названием Activity, вы можете отправить его в широковещательную рассылку, когда будет доступен какой-либо результат. Затем вызывающая активность может перечислить эти трансляции.

22.01.2012
  • Итак, как предотвратить создание нескольких экземпляров (например, списка) в onClick? 02.10.2012

  • 2

    Ответ показан в функции startActivityUncheckedLocked класса ActivityStackSupervisor. До Android 5.x при запуске действия он сначала проверяет launchMode и добавляет FLAG_ACTIVITY_NEW_TASK к launchFlags, если launchMode имеет значение singleTask или singleInstance. Если значение launchFlags действия содержит FLAG_ACTIVITY_NEW_TASK, оно немедленно отправит обратно отмену и позволит новой задаче продолжить запуск в обычном режиме без зависимости от ее инициатора.

    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;
    }
    

    Но в Android 5.x это было изменено, как показано ниже:

    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;
    }
    

    Вот почему onActivityResult работает в Android 5.x, даже если для параметра launchMode установлено значение singleTask или singleInstance.

    07.07.2015

    3

    Что говорит @Peter Knego

    плюс

    вроде работает в 5.1, а не в 4.4.4

    это означает, что onActivityResult срабатывает

    08.06.2015
  • Да, я также наблюдал, как он работает в 5.o и выше, а не в 4.4.4. 20.07.2017

  • 4

    Чтобы уточнить некоторые ответы:

    API ‹ Android 5.x:

    startActivityForResult() в сочетании с режимами запуска singleTask или singleInstance не работает. onActivityResult() будет вызван немедленно с кодом результата Activity.RESULT_CANCELED.

    API ›= Android 5.x:

    startActivityForResult() работает, но режимы запуска singleTask или singleInstance в основном игнорируются, то есть активность запускается в той же задаче, и новая задача не создается.

    Если вы хотите проверить это, запустите adb shell dumpsys activity activities. Я только хочу, чтобы система, по крайней мере, показала мне предупреждение об этом.

    Это изменение также отражено в фрагментах кода, которые @GGCoke опубликовал .

    09.12.2020

    5

    Я знаю, что это довольно поздно, но вы можете иметь эффект OnActivityResult для метода onNewIntent(), потому что это ваша активность singleTask.

    27.01.2016
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..