2011-12-06 38 views
9

Tôi đang sử dụng đoạn mã sau để loại bỏ Childs trên mỗi ViewGroup:Android: Không thể phá hủy hoạt động

protected void onDestroy() { 
    super.onDestroy(); 
    this.liberarMemoria(); 
} 

public void liberarMemoria(){ 
    imagenes.recycleBitmaps(); 
    this.unbindDrawables(findViewById(R.id.RelativeLayout1)); 
    System.gc(); 
} 
private void unbindDrawables(View view) { 
    if (view.getBackground() != null) { 
    view.getBackground().setCallback(null); 
} 
if (view instanceof ViewGroup) { 
    for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
     unbindDrawables(((ViewGroup) view).getChildAt(i)); 
    } 
    ((ViewGroup) view).removeAllViews(); 
    } 
} 

nơi xem: R.id.RelativeLayout1 là một ListView.

Nhưng làm điều này tôi có en ngoại lệ:

E/AndroidRuntime(582): java.lang.RuntimeException: Unable to destroy activity {...}: java.lang.UnsupportedOperationException: removeAllViews() is not supported in AdapterView 

Làm thế nào tôi có thể giải quyết này?

Trả lời

11

Vâng, nhật ký lỗi giải thích khá nhiều: không gọi removeAllViews() trên AdapterView. Và mã của bạn tại một số điểm đáp ứng ViewGroup cũng là AdapterView.

Chỉ cần loại trừ trường hợp này bằng cách sử dụng instanceof kiểm tra hoặc xử lý ngoại lệ với try/catch trình bao bọc.

+1

Bất kỳ ý tưởng nào tại sao AddapterView không hỗ trợ thao tác này? Tôi không thể tìm thấy bất cứ điều gì trong tham chiếu chính thức của AdapterView về nó. – r1k0

+0

@ r1k0, Vâng, đó là bởi vì AdapterView quản lý con của nó trong nội bộ. Bạn không thể thêm/xóa chúng vì điều này có thể phá vỡ trạng thái nội bộ của nó. – inazaruk

0

Xóa dòng đó? Hoặc ít nhất hãy kiểm tra xem hoạt động có được hỗ trợ với trycatch hay không.

Ngoài ra, có một chút rắc rối khi muốn thực hiện điều này trong một phương thức có tên là unbindDrawables, trừ khi nó chỉ là một phương thức được đặt tên sai (không mô tả những gì nó thực hiện đầy đủ).

Bạn có gọi tất cả điều này trong số onDestroy không? Nếu vậy, có lợi ích gì khi làm việc này không? Tôi đã có ấn tượng rằng hệ thống sẽ chăm sóc loại điều này cho bạn.

+0

onDestroy gọi là "liberarMemoria()" và cuộc gọi này "unbindDrawables (..)". Tôi phải làm điều đó một cách thủ công để đảm bảo tiêu diệt Bitmap. –

+0

Phải ... nhưng 'removeAllViews' là không cần thiết và an toàn để xóa ở đây – Craigy

0

Đừng gọi điện thoại. UnsupportedOperationException cho bạn biết rằng phương thức này không được hỗ trợ hoặc chức năng, do đó bạn sẽ phải hoàn thành nhiệm vụ theo cách khác. Tôi không thấy sự cần thiết phải gọi điều này dù sao thì người thu gom rác sẽ xử lý công việc này. Tái chế bitmap nên được thực hiện thủ công nếu bạn cần đảm bảo nó được thực hiện.

+0

Tôi muốn tái chế Bitmap và tôi phải làm thủ công, nhưng cách tốt nhất là gì? –

+0

Tôi không thể nói cho bạn cách tốt nhất mà không nhìn thấy tất cả các nguồn của bạn nhưng bạn nên làm điều đó trong 'onDestroy()' và theo dõi tất cả các đối tượng 'Bitmap' được sử dụng để bạn có thể' recycle() 'chúng. –

7

Xác minh xem ViewGroup của bạn có phải là một phiên bản của AdapterView hay không.

Do something như thế:

if (!(view instanceof AdapterView<?>)) 
    ((ViewGroup) view).removeAllViews(); 

Vì vậy, trên mã của bạn:

if (view instanceof ViewGroup) { 
    for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
     unbindDrawables(((ViewGroup) view).getChildAt(i)); 
    } 
    if (!(view instanceof AdapterView<?>)) 
     ((ViewGroup) view).removeAllViews(); 
} 
Các vấn đề liên quan