Может кто-нибудь объяснить поведение RemoteViews GC? - PullRequest
2 голосов
/ 24 февраля 2011

У меня есть задача загрузки, которая периодически сообщает о прогрессе уведомлению.Некоторое время я использовал один закрытый член RemoveView для обновления каждый раз.

Например:

private RemoteViews mRemoteView;
protected void onCreate(){
    mRemoteView = new RemoteViews( getPackageName(), R.layout.custom_layout )
    contentView.setImageViewResource(R.id.notification_icon, R.drawable.downloads);
    contentView.setTextViewText(R.id.notification_text, "Downloading A File " + (int)( (double)progress/(double)max * 100 ) + "%");
    contentView.setProgressBar(R.id.mProgress, max, progress, false);

    notification.contentView = contentView;
    mNotificationManager.notify(HELLO_ID, notification);
}

protected void onProgressUpdate(Integer... prog) {
    contentView.setProgressBar(R.id.mProgress, max, progress, false);
    mNotificationManager.notify(HELLO_ID, notification);
}

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

Вот код, который работает:

protected void onProgressUpdate(Integer... prog) {
        RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification_layout);
        contentView.setImageViewResource(R.id.notification_icon, R.drawable.downloads);
        contentView.setTextViewText(R.id.notification_text, "Downloading A File " + (int)( (double)progress/(double)max * 100 ) + "%");
        contentView.setProgressBar(R.id.mProgress, max, progress, false);

        notification.contentView = contentView;
        mNotificationManager.notify(HELLO_ID, notification);
    }

1 Ответ

4 голосов
/ 24 февраля 2011

Ссылка, которую вы указали, объясняет это:

RemoteViews используется для создания представления в удаленном процессе.На самом деле это не View, а просто набор команд, которые ставятся в очередь.Затем эта очередь сериализуется, отправляется удаленному процессу, десериализуется, а затем выполняется этот набор действий.Результатом является полностью построенное представление в удаленном процессе.

Как объясняет ссылка: каждый раз, когда вы вызываете метод в RemoteViews, в его очередь добавляются действия.К сожалению, нет способа очистить очередь, поэтому она продолжает расти, пока вы не получите исключение OOM.

Теперь очередь внутренне поддерживается массивом (как и все коллекции).Когда очередь заполняет свой внутренний массив, ей нужно создать новый больший массив и скопировать все старые данные.Затем GC очищает старый массив.Поскольку внутренняя очередь RemoteViews постоянно растет, создаются новые массивы, и GC постоянно очищает старые массивы.

...