onReceive Асинхронные операции и сборка мусора - PullRequest
4 голосов
/ 25 июля 2011

Имеет ли право поток в методе onReceive для сборки мусора до его завершения?

@Override
public void onReceive(final Context context, Intent intent) {
    final int alarmId = intent.getExtras().getInt(EXTRA_ALARM_ID);
    Log.i(TAG, "/onReceive with an alarmVo.id of " + alarmId);

    // RUN MY THREAD
    new Thread(new Runnable() {
        @Override
        public void run() {
            AlarmUtil.setNextAlarm(context, alarmId);
        }
    }).start();
}

Из того, что я понимаю отсюда: http://developer.android.com/reference/android/content/BroadcastReceiver.html это так, но я не совсем уверен.

"все, что требует асинхронной операции, недоступно, потому что вам нужно будет вернуться из функции для обработки асинхронной операции, но в этот момент BroadcastReceiver больше не активен и, следовательно, система свободнаубить свой процесс до завершения асинхронной операции. "

Если он собирает мусор, то как мне обойти это?Каким должен быть мой подход?

1 Ответ

6 голосов
/ 25 июля 2011

Нет. Любой объект Thread, который был запущен с помощью метода start (), который еще не завершен, действует как корень сборки мусора ... ни тот, ни другой объект, на который он строго ссылается, не может быть подвергнут сборке мусора до завершения его метода run ().

Смотрите также эти ответы:

EDIT : Теперь, когда вы добавили дополнительный контекст к вашему вопросу, все стало немного понятнее. Проблема в том, что этот случай - нечто совершенно иное, чем сборка мусора. В случае статически опубликованного BroadcastReceiver (определенного в манифесте приложения с тегом <receiver>) Android может завершить свой процесс после возврата onReceive(Context, Intent). Ваша асинхронная операция не будет остановлена ​​из-за GC, она остановится из-за того, что Android уничтожит процесс, в котором она находится.

Что касается вашего подхода, все зависит от того, чего вы пытаетесь достичь. Если код, который вы хотите выполнить в BroadcastReceiver, может выполняться синхронно, тогда это будет самый простой подход. Я предполагаю, что это невозможно, хотя. В этом случае эта часть документов, кажется, применима (выделено мной):

После того, как вы вернетесь из onReceive (), BroadcastReceiver больше не будет активен, и его процесс хостинга будет иметь такое же важное значение, как и любые другие компоненты приложения, которые в нем работают. Это особенно важно, потому что, если в этом процессе размещался только BroadcastReceiver (частый случай для приложений, с которыми пользователь никогда или недавно не взаимодействовал), то по возвращении из onReceive () система будет считать свой процесс пустым и агрессивно уничтожать чтобы ресурсы были доступны для других более важных процессов.

Это означает, что для более длительных операций вы часто будете использовать Сервис в сочетании с BroadcastReceiver, чтобы поддерживать активный процесс в течение всего времени вашей операции .

Итак, либо выполните код получателя синхронно, либо воспользуйтесь службой, чтобы поддерживать асинхронную операцию достаточно долго, чтобы завершить ее.

(Конечно, все это применимо, только если вы статически регистрируете свой получатель в другом неактивном приложении. Если вы динамически регистрируете его из какого-либо другого активного компонента (скажем, Activity), тогда этот компонент может управлять вашей асинхронной операцией См. этот ответ для получения дополнительной информации.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...