我有一个下载任务,它定期向通知报告进度。有一段时间我每次都使用一个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一直在清理空间,并在很长一段时间内将应用程序减速为爬行。我试着在每次更新时创建一个新的远程视图,这很有效。我想知道这是为什么。我发现一个链接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);
    }

最佳答案

您提供的链接解释了这一点:
RemoteViews用于在远程进程中创建视图。实际上,它不是一个视图,而是一组排队的命令。然后将此队列序列化,发送到远程进程,反序列化,然后执行此操作集。其结果是远程进程中的完全构建视图。
正如link所解释的:每次对remoteviews调用方法时,都会向其队列中添加一个操作。不幸的是,没有办法清除队列,所以它会继续增长,直到出现oom异常。
现在,队列在内部由数组支持(所有集合也是如此)。当队列填满它的内部数组时,它需要创建一个新的更大的数组并复制所有旧数据。然后gc清除旧数组。由于remoteviews内部队列不断增长,因此会创建新的数组,gc会不断清除旧数组。

10-08 17:29