我有一个下载任务,定期向通知报告进度。有一段时间我每次都使用一个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);
}
答案 0 :(得分:4)
您提供的链接说明了这一点:
RemoteViews用于在远程进程中创建View。实际上它不是一个View,而只是一组排队的命令。然后将此队列序列化,发送到远程进程,反序列化,然后执行这组操作。结果是在远程进程中完全构建View。
正如链接所解释的那样:每次在RemoteViews上调用方法时,都会在其队列中添加一个操作。不幸的是,没有办法清除队列,因此它会继续增长,直到你获得OOM异常。
现在,队列在内部由数组支持(与所有集合一样)。当队列填充它的内部数组时,它需要创建一个新的更大的数组并复制所有旧数据。 GC然后清除旧数组。由于RemoteViews内部队列不断增长,因此创建了新阵列,GC不断清理旧阵列。