2011-06-13 27 views
12

Làm thế nào để bạn buộc một NinePatchDrawable để phát hành các byte BitMap nó phân tích ra khỏi 'res'?Làm thế nào để phát hành (buộc, nếu cần thiết) 9-patch (NinePatchDrawable) từ bộ nhớ trong Android?


Là nhà phát triển Android, tôi phải đối mặt với áp lực kiểm soát việc sử dụng bộ nhớ trong trò chơi của mình.

Tôi làm việc để kiểm soát việc sử dụng bộ nhớ bằng cách phát hành tài nguyên nhanh nhất có thể sau khi chúng không còn được sử dụng nữa. Để kết thúc này, tôi duy trì một danh sách tất cả các tài nguyên được nạp và thanh lọc/giải phóng chúng khỏi bộ nhớ ngay khi tôi hoàn thành chúng.

ứng dụng của tôi sử dụng một số loại khác nhau của các nguồn tài nguyên đồ họa

  • bitmap
  • BitMapDrawable
  • drawable
  • NinePatchDrawable

Làm thế nào để giải phóng các đối tượng này ngay bây giờ?

  • Bitmap: Tôi sử dụng "rác()" phương pháp
  • BitMapDrawable: Tôi sử dụng "getBitMap() rác()." Phương pháp
  • drawable: Tôi thiết lập này để null (không làm việc)
  • NinePatchDrawable: Tôi đặt các giá trị này thành không (không hoạt động)

Bạn đã thử gì?

  • Bạn không thể "getBitmap()" một NinePatchDrawable
  • Bạn không thể chuyển đổi một NinePatchDrawable đến một BitMapDrawable (ngay cả khi họ đều Bitmap dựa Drawables)
  • Có vẻ là một cách để phân tích PNG mình , cho ăn các byte vào NinePathDrawable mình - điều này có thể làm cho tôi đến một điểm mà tôi có thể chỉ là "rác()" bitmap tiềm ẩn bản thân mình, nhưng điều đó dường như tôi reinventing the wheel (http://code.google.com/p/android/issues/detail?id=13542)

My Quy tắc hiện tại:

  • Không bao giờ sử dụng @ drawable/trong XML
  • Never android: background trong XML
  • Never android: src trong XML
+0

Bạn có bằng chứng nào mà bạn cần thực sự lo lắng về 9 bản vá? Bạn đã sử dụng MAT và xác định rằng họ đang thắt chặt không gian heap đáng kể? FWIW, tôi không có giải pháp nào để chủ động loại bỏ bản vá 9. Sau đó, một lần nữa, tôi ngạc nhiên khi một nhà phát triển trò chơi đang sử dụng chúng ngay từ đầu, vì tôi không biết rằng họ có vai trò trong sử dụng OpenGL hoặc 'Canvas'. – CommonsWare

+0

@CommonsWare: câu hỏi rất công bằng. Tôi đã sử dụng các kỹ thuật tôi đã học được tại Google IO (http://www.youtube.com/watch?v=_CruQY55HOk) bằng cách sử dụng MAT để xác định rằng * phần * của vấn đề của tôi là chín bản vá. Sử dụng 'recycle()' và 'getBitmap(). Recycle()' trên các tài nguyên có thể vẽ khác của tôi đã làm giảm đáng kể tình hình, nhưng trên một số thiết bị của tôi, tôi vẫn gặp phải lỗi phân bổ VM. Tôi đã hy vọng đạt được hành vi Bitmap nhất quán (miễn phí tất cả chúng theo cùng một cách.) –

+0

@CommonsWare: Trò chơi của tôi (không phức tạp lắm) sử dụng kết hợp Canvas và Hoạt động (được trang trí với 9 bản vá). người chơi rời khỏi Hoạt động Android và sau đó yêu cầu Canvas cấp phát nhiều bộ nhớ trước khi hệ điều hành thu hồi tài nguyên trong Hoạt động chấm dứt. Có rất nhiều giải pháp (tôi nghĩ) vượt quá bộ nhớ giải phóng nhanh hơn - Tôi có thể sử dụng màn hình tải, hoặc không sử dụng quá nhiều bản vá trong các Hoạt động (thay vì Bitmaps thay thế.) –

Trả lời

2

Để có thể sử dụng: @ drawable /, android: background , android: src trong xml, bạn luôn có thể sử dụng các lớp tùy chỉnh.

Vì vậy, thay vì <ImageView android:src="@drawable/bg" /> bạn có thể sử dụng: <com.myPackage.CustomImageView android:src="@drawable/bg" />

Thần trong CustomImageView trong constructor bạn có thể lấy tài liệu tham khảo để xml của bạn thuộc tính:

 
private Drawable bg2; 
private Drawable bg1; 
public void CustomImageView(Context context, Attrs attrs) 
{ 
    super(context, attrs); 

    // Use this to get references to your xml attributes 
    int resourceId = attrs.getAttributeResourceValue("android", "src", 0); 
    bg1 = getResources().getDrawable(resourceId); 

    // Or for the 'background' attribute 
    resourceid = attrs.getAttributeResourceValue("android", "background", 0); 
    bg2 = getResources().getDrawable(resourceId); 

    // Now you can recycle() your 'bg' whenever you're done 
} 

Bằng cách này, bạn có thể trích xuất tài liệu tham khảo từ xml của bạn. Và tái chế() chúng khi bạn nghĩ rằng nó phù hợp

+0

Tôi đang làm việc để nhận mã này để hoạt động và thử nghiệm ... cảm ơn bạn đã trả lời, tôi sẽ quay lại! –

+0

Điều này có phù hợp với bạn không? – Entreco

+0

Không có điều này không làm việc cho tôi, xin lỗi. –

1

Tôi cũng cảm thấy thất vọng bởi lỗi lỗi thời. Ứng dụng của tôi đã ném một lỗi outofmemory bất cứ khi nào người dùng đi từ hoạt động này sang hoạt động khác. Thiết lập drawables của tôi để null và gọi System.gc() không hoạt động, không tái chế bitmapDrawables của tôi với getBitMap().recycle(). Android sẽ tiếp tục ném lỗi outofmemory với cách tiếp cận đầu tiên, và nó sẽ ném một thông báo lỗi canvas bất cứ khi nào nó cố gắng sử dụng một bitmap tái chế với cách tiếp cận thứ hai.

Tôi đã thực hiện một phương pháp tiếp cận thứ ba. Tôi đặt tất cả các khung nhìn thành null và nền thành màu đen. Tôi làm việc này trong phương thức onStop() của mình. Đây là phương thức được gọi ngay khi hoạt động không còn hiển thị nữa. Phương thức onDestroy() có thể không được gọi. Ngoài ra, nếu dọn dẹp được thực hiện trong phương thức onPause(), người dùng sẽ nhận được một màn hình màu đen trước khi chuyển sang màn hình tiếp theo.

Để ngăn màn hình đen xuất hiện nếu người dùng nhấn nút quay lại trên thiết bị, sau đó tải lại hoạt động trong phương thức onRestart() bằng cách gọi phương thức startActivity (getIntent()) và finish().

Lưu ý: không thực sự cần thiết để thay đổi nền thành màu đen.

Các vấn đề liên quan