2010-08-31 38 views
10

Tôi đang phát triển một ứng dụng có dịch vụ hiển thị tiến độ của bộ hẹn giờ trong vùng thông báo (với thanh tiến trình và văn bản). Tôi đã trích xuất dưới đây một ví dụ đơn giản với cùng một vấn đề.Sử dụng bộ nhớ rất lớn trong các thông báo

Mã của Dịch vụ:

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); 
    } 
} 

Mã của 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); 
    } 
} 

Vấn đề là sử dụng bộ nhớ khổng lồ. Đây là kết quả 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 

Tôi nghĩ rằng đó là quá nhiều bộ nhớ và sau một thời gian treo điện thoại với các đầu ra này:

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 

Bất cứ ai cũng biết làm thế nào tôi có thể làm điều đó mà không sử dụng quá nhiều bộ nhớ ?

Cảm ơn!

+0

Xem một lỗi mở về đề tài này: http://code.google.com/p/android/issues/detail?id=13941 –

Trả lời

2

Hãy thử sử dụng DDMS để loại bỏ các phân bổ - điều đó sẽ cho bạn thấy những gì các đối tượng đang được phân bổ và ở đâu.

Tôi đoán là thanh tiến trình đang phân bổ một số bitmap trên mỗi cuộc gọi đến setProgressBar (5 lần mỗi giây) và đó là những gì được chuyển qua bộ nhớ. Những gì không rõ ràng là tại sao bạn đang chạy ra ngoài - GC dường như được chọn nó lên, vì vậy một cái gì đó phải được rò rỉ.

+1

tôi đã sử dụng thanh tiến trình trong thông báo một lần và tôi đã trải nghiệm rằng điện thoại đã thực sự chậm khi cố cập nhật tiến trình. Vì vậy, tôi đã phải giảm rất nhiều cập nhật frequence. –

+0

Vâng! Đó cũng là giải pháp của tôi, nhưng tôi không biết cách tránh hoặc giảm hành vi đó. – Urizev

10

Tôi tình cờ gặp vấn đề tương tự ... Có vẻ như nếu tôi không "lưu" RemoteView và thông báo trong dịch vụ, nhưng tạo lại chúng từ đầu trong quá trình "cập nhật", sự cố này sẽ biến mất. Có, tôi biết nó không hiệu quả, nhưng ít nhất điện thoại không khởi động lại sau 10-15 phút vì nó hết bộ nhớ.

+0

Cảm ơn, có vẻ như đã làm trò lừa. – plouh

+0

Tôi gặp sự cố tương tự khi điện thoại của tôi bị rơi (chú giải HTC) hoặc một phần của hệ điều hành bị lỗi (Sony Ericsson Xperia Mini Pro). Việc tái tạo RemoteView trên mỗi bản cập nhật đã giải quyết được vấn đề. – slott

+0

Bí quyết rất hay, Cảm ơn bạn – NullPointer

1

Vấn đề với giải pháp này là nếu đó là thông báo đang diễn ra, nó sẽ "hop" trên thanh trạng thái và ngăn thông báo khi các thông báo đang diễn ra khác được cập nhật.

Tôi đã thử nhiều thứ, bao gồm việc tuyên bố thành viên RemoteView và Notification là dễ bay hơi (vì RemoteView là chủ đề chéo), dường như hoạt động nhưng chỉ làm chậm sự cố.

Điều tôi giải quyết là sử dụng thành viên choke và "lưu vào bộ nhớ cache" Chế độ xem từ xa và Thông báo tối đa X lần, sau đó tạo lại chúng.

Khi thành viên của họ được đặt thành vô hiệu, lỗ hổng nhỏ dường như được giải phóng.

0

Tôi gặp sự cố tương tự. Tôi đã có một Service trình bày một Notification với thanh tiến trình tương ứng với tệp tải xuống. Ứng dụng sẽ gặp sự cố với số OutOfMemoryError, khoảng 10 giây sau khi người dùng nhấp vào Notification đưa họ đến ứng dụng.

Tôi thấy rằng việc thêm .setOngoing(true); vào Trình tạo đã khắc phục sự cố này.

công NotificationCompat.Builder setOngoing (boolean liên tục)

Đặt cho dù đây là một thông báo liên tục. thông báo đang thực hiện khác với thông báo thường xuyên trong các cách sau:

  • thông báo đang thực hiện đều được sắp xếp trên các thông báo thường xuyên trong bảng thông báo.

  • Thông báo đang diễn ra không có nút đóng 'X' và không bị ảnh hưởng bởi nút "Xóa tất cả".

Ví dụ:

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); 
Các vấn đề liên quan