有人可以解释RemoteViews GC的行为吗?

时间:2011-02-23 21:11:24

标签: android memory garbage-collection

我有一个下载任务,定期向通知报告进度。有一段时间我每次都使用一个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);
}

然而,我发现GC不断清理空间并将该应用程序放慢速度。我尝试每次更新时创建一个新的RemoteViews,这是有效的。我想知道为什么会这样。我找到了一个有用的链接here,但我正在寻找更多信息。

以下是有效的代码:

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 个答案:

答案 0 :(得分:4)

您提供的链接说明了这一点:

RemoteViews用于在远程进程中创建View。实际上它不是一个View,而只是一组排队的命令。然后将此队列序列化,发送到远程进程,反序列化,然后执行这组操作。结果是在远程进程中完全构建View。

正如链接所解释的那样:每次在RemoteViews上调用方法时,都会在其队列中添加一个操作。不幸的是,没有办法清除队列,因此它会继续增长,直到你获得OOM异常。

现在,队列在内部由数组支持(与所有集合一样)。当队列填充它的内部数组时,它需要创建一个新的更大的数组并复制所有旧数据。 GC然后清除旧数组。由于RemoteViews内部队列不断增长,因此创建了新阵列,GC不断清理旧阵列。