2010-08-31 60 views
10

我正在开发一个应用程序与服务,显示在通知区域(与进度条和文本)计时器的进度。我在下面解释了一个相同问题的简单例子。巨大的内存使用通知

服务的代码:

public class TNService extends Service { 
    private NotificationManager nm; 
    private Notification notification; 
    private RemoteViews remoteView; 

    @Override 
    public void onCreate() { 
     nm = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); 
     notification = new Notification(android.R.drawable.stat_sys_download, 
       "My notification", 
       System.currentTimeMillis()); 
     remoteView = new RemoteViews(this.getPackageName(), 
       R.layout.notification); 
     remoteView.setImageViewResource(R.id.icon, android.R.drawable.stat_sys_download); 
     remoteView.setTextViewText(R.id.text, ""); 
     remoteView.setProgressBar(R.id.progress, 100, 0, false); 
     notification.flags = Notification.FLAG_NO_CLEAR; 
     notification.contentView = remoteView; 
     notification.contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, 
       TNActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); 

     Timer timer = new Timer(); 
     timer.schedule(new TNTask(this), 0, 200); 
    } 

    @Override 
    public IBinder onBind(Intent arg0) { 
     return null; 
    } 

    public void updateNotification(int progress) { 
     remoteView.setProgressBar(R.id.progress, 1000, progress, false); 
     remoteView.setTextViewText(R.id.text, "Progress: " + progress); 
     nm.notify(0, notification); 
    } 
} 

一个TimerTask的代码:

public class TNTask extends TimerTask { 
    private TNService service; 
    private int progress; 

    public TNTask(TNService s) { 
     this.service = s; 
     this.progress = 0; 
    } 

    @Override 
    public void run() { 
      progress = (progress + 1) % 1000; 
     this.service.updateNotification (progress); 
    } 
} 

的问题是巨大的内存使用情况。这里是logcat的输出:

D/dalvikvm(11985): GC_EXPLICIT freed 1258 objects/84016 bytes in 1157ms 
D/dalvikvm( 85): GC_FOR_MALLOC freed 52216 objects/1900968 bytes in 130ms 
D/dalvikvm( 85): GC_FOR_MALLOC freed 49465 objects/1805248 bytes in 125ms 
D/dalvikvm( 85): GC_FOR_MALLOC freed 53106 objects/1909992 bytes in 134ms 
D/dalvikvm(12008): GC_EXPLICIT freed 1604 objects/100944 bytes in 90ms 
D/dalvikvm( 85): GC_FOR_MALLOC freed 53011 objects/1937160 bytes in 135ms 
D/dalvikvm( 85): GC_FOR_MALLOC freed 49806 objects/1817992 bytes in 143ms 
D/dalvikvm( 85): GC_FOR_MALLOC freed 49016 objects/1769536 bytes in 135ms 
D/dalvikvm( 85): GC_FOR_MALLOC freed 53509 objects/1941064 bytes in 145ms 
D/dalvikvm( 85): GC_FOR_MALLOC freed 49895 objects/1842312 bytes in 146ms 
D/dalvikvm( 85): GC_FOR_MALLOC freed 48728 objects/1774496 bytes in 150ms 
D/dalvikvm( 85): GC_FOR_MALLOC freed 47557 objects/1701976 bytes in 146ms 
D/dalvikvm( 85): GC_FOR_MALLOC freed 53540 objects/1903808 bytes in 156ms 
D/dalvikvm( 85): GC_FOR_MALLOC freed 48997 objects/1784048 bytes in 158ms 
D/dalvikvm( 85): GC_FOR_MALLOC freed 48326 objects/1776864 bytes in 158ms 
D/dalvikvm( 85): GC_FOR_MALLOC freed 47566 objects/1742488 bytes in 169ms 
D/dalvikvm( 85): GC_FOR_MALLOC freed 47606 objects/1703416 bytes in 170ms 
D/dalvikvm( 162): GC_EXPLICIT freed 11238 objects/641368 bytes in 1064ms 

我认为这是太多的内存,并经过一段时间的电话挂起这个输出:

D/dalvikvm( 85): GC_FOR_MALLOC freed 0 objects/0 bytes in 241ms 
I/dalvikvm-heap( 85): Clamp target GC heap from 24.008MB to 24.000MB 
I/dalvikvm-heap( 85): Grow heap (frag case) to 24.000MB for 52-byte allocation 
I/dalvikvm-heap( 85): Clamp target GC heap from 26.008MB to 24.000MB 
D/dalvikvm( 85): GC_FOR_MALLOC freed 0 objects/0 bytes in 241ms 
I/dalvikvm-heap( 85): Clamp target GC heap from 24.008MB to 24.000MB 
I/dalvikvm-heap( 85): Grow heap (frag case) to 24.000MB for 24-byte allocation 
I/dalvikvm-heap( 85): Clamp target GC heap from 26.008MB to 24.000MB 
D/dalvikvm( 85): GC_FOR_MALLOC freed 0 objects/0 bytes in 247ms 
I/dalvikvm-heap( 85): Clamp target GC heap from 24.009MB to 24.000MB 
I/dalvikvm-heap( 85): Grow heap (frag case) to 24.000MB for 28-byte allocation 
I/dalvikvm-heap( 85): Clamp target GC heap from 26.009MB to 24.000MB 
D/dalvikvm( 85): GC_FOR_MALLOC freed 0 objects/0 bytes in 247ms 
I/dalvikvm-heap( 85): Clamp target GC heap from 24.009MB to 24.000MB 

任何人都知道我怎么能做到这一点,而无需使用这么多的内存?

谢谢!

+0

参见受试者的开放缺陷:http://code.google.com/p/android/issues/detail?id=13941 – 2012-08-09 08:11:14

回答

2

尝试使用DDMS倾倒出来的拨款 - 应该表现出你被分配和哪里是什么物体。

我的猜测是,进度条在每次调用setProgressBar(每秒5次)分配一些位图和那正是搅动通过内存。不清楚的是你为什么会用完--GC似乎在捡起它,所以有些东西一定是漏水的。

+1

我在通知中一次使用了一个进度条,并且我经历过当尝试更新进度时手机变得非常慢。所以,我不得不减少更新频率。 – 2010-09-03 11:11:54

+0

是啊!这也是我的解决方案,但我不知道如何避免或减少这种行为。 – Urizev 2010-12-08 13:31:00

10

我偶然发现了同样的问题......看起来如果我不在服务中“缓存”RemoteView和Notification,而是在“更新”例程中重新创建它们,则此问题会消失。是的,我知道它效率不高,但至少手机在10-15分钟后不重新启动,因为内存不足。

+0

谢谢,似乎是做伎俩。 – plouh 2011-01-06 11:21:08

+0

我有我的手机崩溃(HTC传说)或部分操作系统崩溃(索尼爱立信Xperia Mini Pro)完全相同的问题。在每个更新上重新创建RemoteView解决了这个问题。 – slott 2012-06-05 19:37:17

+0

非常好的技巧,谢谢 – NullPointer 2013-03-10 20:39:03

1

这个解决办法的问题是,如果它是一个持续的通知,将在状态栏和通知面板上“跳”其他正在进行的通知将被更新。

我已经试过几件事,包括宣布远程视窗和通知会员挥发性(因为远程视窗是跨线程),这似乎工作,但只是放缓的问题。

我定居在用一个节流件,而“cacheing”的远程视窗和通知最多X次,然后重新创建它们。

当它们的成员设置为null时,小泄漏似乎被释放。

0

我有一个类似的问题。我有一个Service,提供了一个Notification与进度条相对应的文件下载。在用户点击Notification将它们带到应用程序后大约十秒钟,该应用程序会崩溃,出现OutOfMemoryError

我发现,添加.setOngoing(true);到Builder解决了这个问题。

公共NotificationCompat.Builder setOngoing(布尔正在进行)

设置,这是否是一个持续的通知。 正在进行的通知从通知定期在以下方面不同:

  • 正在进行通知上述通知面板的常规通知进行排序。

  • 正在进行的通知没有“X”关闭按钮,并且不受“全部清除”按钮的影响。

实施例:

NotificationCompat.Builder builder = new NotificationCompat.Builder(context).setAutoCancel(true) 
                 .setDefaults(Notification.DEFAULT_ALL) 
                 .setContentTitle("Downloading").setContentText("Download in progress...) 
                  .setSmallIcon(android.R.drawable.stat_sys_download) 
                  .setSound(null) 
                  .setDefaults(0) 
                  .setOngoing(true);