Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Инициализация YandexAds SDK запускает второй процесс приложения #296

Open
aaal-dev opened this issue Dec 4, 2024 · 15 comments
Labels
transmitted Issue transmitted to inner service

Comments

@aaal-dev
Copy link

aaal-dev commented Dec 4, 2024

Используем AppLovin, с кучей адаптеров, в том числе и Yandex.
Имеется проблема запуска второго процесса приложения в момент инициализации YandexAds.
Пока не можем понять причин. И может быть вы можете помочь с понимаем?

Без Yandex адаптера проблема не проявляется.

Пробовали добавлять отключение автоматической инициализации в манифест. Но в последствии, при показе рекламы всё равно происходит инициализация YandexAds и в месте с этим создание второго процесса.

У нас в приложении основной код обрабатывается через JNI в отдельном потоке, поэтому мы ловим рандомные ошибки и падения из-за созданного второго процесса

@mobile-ads-github
Copy link
Collaborator

Спасибо за Ваше обращение, для разбора создана задача с номером ADLIBGITHUB-11. Мы ознакомимся и вернемся с ответом как можно скорее, возможно запросим дополнительную информацию.

Thank you for your message, a task with the number ADLIBGITHUB-11 has been created for analysis. We will get acquainted and return with the answer as soon as possible, we may request additional information.

@mobile-ads-github mobile-ads-github added the transmitted Issue transmitted to inner service label Dec 4, 2024
@stayf
Copy link

stayf commented Dec 10, 2024

Попробуйте убрать код инициализации в Application. Вероятно вам поможет. Я решил это так:

//Фикс бага возникшего из-за рекламной библиотеки яндекса. У них запускается метрика в другом процессе.
//И в этом случае вызывается onCreate у Application.

   public String getAppProcessName() {
        if (SDK_INT >= Build.VERSION_CODES.P) {
            return Application.getProcessName();
        } else {
            try {
                Class<?> activityThread = Class.forName("android.app.ActivityThread", false, GreedyScheduler.class.getClassLoader());
                Method currentProcessName = activityThread.getDeclaredMethod("currentProcessName");
                currentProcessName.setAccessible(true);
                final Object packageName = currentProcessName.invoke(null);
                if (packageName instanceof String) return (String) packageName;
            } catch (Throwable exception) {
            }
            int pid = Process.myPid();
            ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
            if (am != null) {
                List<ActivityManager.RunningAppProcessInfo> processes = am.getRunningAppProcesses();
                if (processes != null && !processes.isEmpty()) {
                    for (ActivityManager.RunningAppProcessInfo process : processes) {
                        if (process.pid == pid) {
                            return process.processName;
                        }
                    }
                }
            }
        }
        return null;
    }

    boolean isMainProcess() {
        return TextUtils.equals(getPackageName(), getAppProcessName());
    }

В application:
@Override public void onCreate() { super.onCreate(); if (!isMainProcess()) return; }

@aaal-dev
Copy link
Author

aaal-dev commented Dec 10, 2024

Спасибо, @stayf. Попробуем.
У нас вызывается не только onCreate, а создаётся отдельный новый процесс всего приложения, который за собой тянет все сопуствующие вызовы методов всех элементов. Создаётся основная активность приложения и так далее. Я, лично, был сильно удивлён. Так как визуально это никак не фиксируется. Приложение работает, как работало. Отловить странное поведение удалось после того, как я добавил логи во всех методах жизненого цикла приложения и активностей. После начал отключать разные части приложения, чтобы понять, что приводит к неправильному поведению. После чего стало чётко понятно, что после инициализации YandexAds, запускался новый процесс

@aaal-dev
Copy link
Author

Не помогло. Процесс всё равно стартует и тянет за собой всё остальное. Отменить этот механизм нельзя. Я так понимаю, что проблема именно в библиотеке AppMetrika?

@stayf
Copy link

stayf commented Dec 12, 2024

@aaal-dev Да так уже много лет. Не знаю почему они так сделали. Но это действительно доставляет проблемы, но я не думаю что они поменяют что-то в ближашие пол года-год. Они отвечают на issue спустя месяц и более, а фиксят их спустя несколько месяцев)

@aaal-dev
Copy link
Author

Я нашёл их библиотеку. Будет свободное время - посмотрю, что там сделали

@UnateD
Copy link

UnateD commented Feb 5, 2025

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

@aaal-dev
Copy link
Author

aaal-dev commented Feb 5, 2025

@UnateD, спасибо за ответ. Но возникает вопрос, а как спрятать код от основного процесса, если не возможно понять какой процесс основной? Хранить ID процесса и на каждый чих проверять соответствие? Выглядит как глупость. Проблема же в том, что процесс в принципе должен быть один. Это же нарушение логики работы приложения для Android. Нельзя будет использовать слушателей жизненого цикла приложения. Лучшим решением тут я считаю отказ от Яндекс Рекламы, пока они не починят эту проблему

@aaal-dev
Copy link
Author

aaal-dev commented Feb 5, 2025

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

@UnateD
Copy link

UnateD commented Feb 5, 2025

Нет необходимости проверять на каждый чих - у Вас есть общие участки для обоих процессов, достаточно предусмотреть в них развилки (если они действительно общие). В Вашем случае, вероятнее всего, общий участок один . Не совсем понял про создание activity - компоненты приложения по-умолчанию запускаются в базовом процессе, если не указано обратного. Если в Вашем манифесте этого нет, то единственной общей точкой, которую проходит старт процессов, у вас является onCreate у наследника Application класса. Здесь Вам необходимо добавить проверку на процесс, который проходит onCreate. Если он основной - инициализируетесь как обычно. В противном случае не инициализируете то, чего не хотите видеть в процессе Яндекса

@aaal-dev
Copy link
Author

aaal-dev commented Feb 5, 2025

Странно. Так как у нас инициализируется всё в плоть до броадкастеров, ресиверов и основной активности. Это как раз мешает нам. Если бы можно было отключить все инициализации объектов приложения прописанные в манифесте, который проходят автоматически, мы бы это уже сделали. Но увы. Тут как бы получается, что из-за такого поведения библиотеки Яндекс Рекламы нам необходимо пересматривать архитектуру всего приложения, что нам на данный момент не подходит

@mobile-ads-github
Copy link
Collaborator

Здравствуйте!
Действительно, в рамках инициализации YandexAds sdk инициализируется и sdk метрики, которая в свою очередь запускает дополнительный процесс приложения.

Для каждого процесса в рамках приложения создается свой инстанс Application или его наследника, и, соответственно, весь код в коллбэках Application выполняется для каждого процесса. Чтобы изолировать логику коллбэков Application только для основного процесса необходимо добавить проверку на имя процесса, как уже предложил @stayf, в каждый из переопределенных коллбэков Application.

Основные компоненты Android приложения по умолчанию создаются и запускаются только в основном процессе приложения, если в AndroidManifest не указано иного.
Для <activity> и <provider> компонентов проверьте пожалуйста, не указан ли у вас атрибут android:multiprocess="true". Этот атрибут сообщает системе о том, что соответствующий компонент может быть запущен в любом процессе приложения.

@aaal-dev
Copy link
Author

aaal-dev commented Feb 6, 2025

Спасибо за предожение. У нас нет атрибута android:multiprocess="true". То, что предложил @stayf мы уже попробовали. В его предложении проверка на другой процесс не предотвращает запуск элементов приложения, которые прописаны в манифесте, и, по логике работы Android приложения, должны быть запущены автоматически. В его случае лишь отбрасывается выполнение кода ниже проверки. А это означает, что такую проверку нужно расставлять везде, где, так или иначе, происходит взаимодействие бизнес-логики с механизмами Android приложения. Что означает, что необходимо перерабатывать архитектуру приложения, о чём я уже указал. Для нас это не подходит, так как нелогичное создание отдельного процесса всего приложения при уже имеющемся - это неадекватное поведение приложения

@UnateD
Copy link

UnateD commented Feb 6, 2025

А как Вы понимаете то, что прочие компоненты стартуют из иного процесса..? Вы наблюдаете двойные запуски компонентов? Если добавить отправку логов из этих компонентов и вывести в них id процесса - действительно ли есть дублирование с указанием разных id процессов? Ситуация такова, что в базовом исполнении Android НЕ использует компоненты в процессе отличном от основного - об этом указал я ранее, об этом пишет выше поддержка Яндекс, об этом говорит и справка
Использование отдельного процесса для метрики (мое личное мнение) не самое ожидаемое решение и, более того, использование принудительное метрики в кейсе, когда я добавляю рекламу, а не метрику. Однако это не создает каких-то проблем, если конфигурация Вашего проекта штатная. Исходя из того, что Вы описываете, либо конфигурация от штатной отличается, либо Вы можете ошибаться в том, что второй процесс использует Ваши компоненты - он о них даже не знает, если они нужным образом не отмечены, чего не добиться иным образом, кроме как руками это сделать.

@aaal-dev
Copy link
Author

aaal-dev commented Feb 6, 2025

Мы видим это по логам. Если бы не логирование вызова методов компонентов, то возможно бы и не заметили этого поведения. И для нас такое поведение то же является странностью. На текущий момент в нашем случае отключение Яндекс Рекламы полностью избавляет от странного поведения.

Изначально у нас при подключении Яндекс Рекламы старт приложения замедлился. Не критично, но для нас заметно. Именно поэтому мы начали логирование, чтобы проконтролировать запуски компонентов. А после начали появляться рандомные падения приложения во время работы. Замедление старта связано, как раз с инициализацией Яндекс Рекламы, это мы выявили быстро. И нам понятно, что с этим ничего не поделать, просто смирились. То есть это не является для нас проблемой. А падения происходят из-за запуска компонентов для второго процесса. Они как бы не понимают, что запущены в отдельно процессе и пытаются обратиться к данным, доступ к которым у них нет.

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

Спасибо за помощь

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
transmitted Issue transmitted to inner service
Projects
None yet
Development

No branches or pull requests

4 participants