2016-04-08 22 views
2

Genel Bakış: Sohbet uygulaması yapıyorum. Şimdiye kadar, sohbet öğelerimi listede yüklemek için CursorAdapter'i bir Listview ile kullanıyordum. Ama şimdi, RecyclerView.Adapter ile RecyclerView ve whatsapp gibi bir "Load More" işlevselliği kullanmak için kodu yeniden düzenlemeyi planlıyorum.RecyclerView.Adapter içindeki pek çok öğe - Bellek Sorunu

Yayım: Bellek tüketimi. CursorAdapter ile görüntülenebilir alandaki öğeler Çöp Toplama işlemine giriyordu, ancak şimdi CustomModal'ımın bir ArrayListini kullanıyorum, listeden tüm öğeleri yükledikten sonra ("Daha Fazla Yükle" düğmesine tıklayarak) Görüyorum Hafıza kayıtlarındaki yüksek hafıza tüketimi (Çöp Toplama Yok).

Şimdi tahmin edeyim, bir öğeyi ArrayList'e yüklüyorum ve bu da soruna neden oluyor. Bu mu?

Sorunu önleme veya sorunu en iyi duruma getirmenin bir yolu var mı?

DÜZENLEME: burada tam kod sonrası, ama burada uyguladık Adaptörü tür snippet'idir edilemez: Bütün ArrayList değiştirme yerine

public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MyViewHolder> { 

    private ArrayList<MyModal> mMyModals; 

    public MessageAdapter(ArrayList<MyModal> mMyModals) { 
     this.mMyModals = mMyModals; 
     //... Some fields initialization here 
    } 

    public void changeList(ArrayList<MyModal> myModals, boolean isLoadMoreEnabled){ 
     this.mMyModals = myModals; 
     //... Some fields initialization here 
     notifyDataSetChanged(); 
    } 

    public void toggleLoadMore(boolean isLoadMoreEnabled){ 
     if(isLoadMoreEnabled){ 
      //..Checks if load more is already enabled or not 
      //..If not then enables it by adding an item at 0th poition of MyModal list 
      //..Then notifyDataSetChanged() 
     }else{ 
      //..Checks if load more is already disabled or not 
      //..If not then disables it by removing an item at 0th poition of MyModal list 
      //..Then notifyDataSetChanged() 
     } 
    } 

    @Override 
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     MyViewHolder messageViewHolder = null; 
     View itemLayoutView = null; 

     MyModal.MessageType messageType = MyModal.MessageType.getMessageTypeFromValue(viewType); 
     switch (messageType){ 
      case MESSAGE_TYPE1: 
       itemLayoutView = LayoutInflater.from(parent.getContext()) 
         .inflate(R.layout.layout1, null); 
       messageViewHolder = new Type1ViewHolder(itemLayoutView); 
       break; 
      case MESSAGE_TYPE2: 
       itemLayoutView = LayoutInflater.from(parent.getContext()) 
         .inflate(R.layout.layout2, null); 
       messageViewHolder = new Type2ViewHolder(itemLayoutView); 
       break; 
     } 

     return messageViewHolder; 
    } 

    @Override 
    public void onBindViewHolder(MyViewHolder holder, int position) { 
     final MyModal myModal = mMyModals.get(position); 
     MyModal.MessageType messageType = myModal.getMessageType(); 
     holder.initialize(myModal); 
    } 

    @Override 
    public int getItemCount() { 
     return (mMyModals != null)?mMyModals.size():0; 
    } 

    @Override 
    public int getItemViewType(int position) { 
     return mMyModals.get(position).getMessageType().getValue(); 
    } 

    public abstract class MyViewHolder extends RecyclerView.ViewHolder { 

     public MyViewHolder(View itemLayoutView) { 
      super(itemLayoutView); 
     } 

     public abstract void initialize(MyModal myModal); 
    } 

    class Type1ViewHolder extends MyViewHolder { 

     //...Variables 

     public Type1ViewHolder(View itemLayoutView) { 
      super(itemLayoutView); 
      //...variables initialization here 
     } 

     @Override 
     public void initialize(MyModal myModal) { 
      //...Setting values in view using myModal 
     } 
    } 

    class Type2ViewHolder extends MyViewHolder { 

     //...Variables 

     public TextViewHolder(View itemLayoutView) { 
      super(itemLayoutView); 
      //...variables initialization here 
     } 

     @Override 
     public void initialize(MyModal myModal) { 
      //...Setting values in view using myModal 
     } 
    } 
} 
+0

Bağdaştırıcı sınıfınızı gösterebilir misiniz? İhtiyaç duyduğunuzdan daha fazla kez başlatıyor olabilirsiniz. Eğer kod –

+0

Hey Ragesh, bir kez kod kontrol edin, ben kod ile sorumu güncelledik. Bu konuyu burada anlamama yardımcı olabilir misiniz? – Wanted

cevap

1

İlk: Burada

public void changeList(ArrayList<MyModal> myModals, boolean isLoadMoreEnabled){ 
    this.mMyModals = myModals; 
    //... Some fields initialization here 
    notifyDataSetChanged(); 
} 

Yeni arraylist oluştururken ve mMyModals bunu atıyorsunuz. Bu, bu noktada 2 arraylist var demektir ve bunlar gerekenden iki kat fazla alan kaplarlar. GC beklediğiniz şekilde çalışmaz. Arteryist aktivitenizde başlatıldığı için arraylist devam ettiği sürece devam edecek ve ilk arraylist de olacaktır.

Etkinliğinizde yeni bir arraylist oluşturmak ve değiştirmek içinList'e geçirmek yerine. Sadece eski arraylist temizlemek ve aşağıda

 public void changeList(ArrayList<MyModal> myModals, boolean isLoadMoreEnabled){ 
    this.mMyModals.clear(); 
    this.mMyModels.addAll(myModels); 
    //... Some fields initialization here 
    notifyDataSetChanged(); 
} 

i belli değil isem bana bildirin yapabilirsiniz adaptör changeList yönteminde de that.And geçmektedir. Ayrıca bu çalışmazsa etkinlik kodunuzu da gösterin.

+0

Teşekkürler @Ragesh, yarın deneyecek. – Wanted

+0

Bu (clear() ve addAll() yöntemi) aslında çalıştı. En azından GC şimdi bunu yapabiliyor. Tekrar teşekkürler. – Wanted

+0

Sonra doğru olarak işaretleyiniz. –

1

ve notifyDataSetChanged'u arayarak, öğeleri ArrayList'a eklemeyi deneyin ve notifyItemRangeInserted(int positionStart, int itemCount)'u arayın, belki bu işe yarayabilir. Ayrıca, Adapter'un ArrayList'u değiştirmeniz gerekmez. Sizin Activity/Fragment muhtemelenile aynıdır, sadece bu listeyi Activity/Fragment içinde düzenliyor ve daha sonra notifyItemRangeInserted(int positionStart, int itemCount) numaranızı çağırarak yapmalısınız. Ayrıca, tüm mesajları almak yerine, yalnızca bir sonraki X mesajını almayı deneyebilirsiniz, böylece daha önce aldığınız mesajları almazsınız (bunu daha önce yapmadıysanız). Her şeyden

+0

Teşekkürler Jeffalee, deneyecek. Ama yine de, arraylist referansıma yeni bir nesne atarsam, eski nesne GC için uygun olur, doğru mu? Ama ben bunu görmüyorum. Uygulamam tam 128Mb bellek tüketiyor – Wanted

İlgili konular