2010-08-31 64 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);