为什么在更新进程中NotificationManager的工作如此缓慢?

6

我通过NotificationManager发布文件上传进度,但在更新进度UI时会冻结。

我使用NotificationCompat.Builder,并将其缓存在类字段中。因此,进度发布非常简单:

manager.notify(id, uploader.
    setProgress(MAX_PROGRESS, (int) (progress * 100), false).
    build()
);

更新进度保证从主线程执行(在Handler装饰器中包装)。

this.request.setCallback(new UploaderDecorator(this.request.getCallback()));

进展的发布如下所示:
long total = file.length();
long uploaded = 0;
int bytesRead = input.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
    output.write(buffer, 0, bufferSize);
    uploaded += bytesRead;
    callback.onUploadProgress(activeFile, ((float) uploaded / total));
    bytesRead = input.read(buffer, 0, bufferSize);
}

所以为什么它运行得如此缓慢?

"更新进度被保证在主线程中执行(使用Handler装饰器包装)"-- 您不需要从主应用程序线程更新 Notification。实际上,这可能会导致问题。 - CommonsWare
@CommonsWare 移除了修饰器,将id进程进行了比较,因为它们不同,但问题仍然存在。 问题在于通知栏,我的应用程序速度相同。 - bvitaliyg
也许是因为通知发送得太频繁了? - bvitaliyg
1
我在通知中看到的大多数下载进度条似乎并不经常更新——可能每隔几秒钟才更新一次。根据bufferSize的大小,你很有可能会使NotificationManager过载。 - CommonsWare
@CommonsWare bufferSize 是 1024。我应该增加它吗?增加到什么值? - bvitaliyg
1
无论Notification问题如何,我肯定会使用更大的缓冲区,仅出于性能考虑。最少8-16K。 - CommonsWare
1个回答

10

这是一种常见的行为。您不应该频繁更新通知管理器。您应该决定一个更新间隔,例如每秒更新两次。

例如,

long startTime;
long elapsedTime = 0L;

if (elapsedTime > 500) {
    new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override
        public void run() {
            mBuilder.setProgress(100, (int) newValue, false);
            mNotifyManager.notify(notificationID, mBuilder.build());

            startTime = System.currentTimeMillis();
            elapsedTime = 0;
        }
    });

    Log.d("Andrognito", newValue + "Progress");
}
else
    elapsedTime = new Date().getTime() - startTime;

这对我来说非常完美,而且不会冻结通知。

你知道我可以设置的最小间隔是多少吗? - Vlado Pandžić
非常完美地适用于多个通知!谢谢 - Tamim Attafi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接