2016-12-06 3 views
2

Я столкнулся с исключением outOfMemory при загрузке изображений с помощью Picasso. Я создаю picasso builder с OkHttp и создал класс Picasso Singleton для кэширования изображений.OutOfMemory Exception - для adapter.notifiyDataSetChanged() при загрузке изображений с помощью picasso

Сценарий: У меня есть 100+ изображений изображений, которые необходимо загрузить. Я получаю изображения в наборах, и каждый набор имеет 25 URL-адресов изображений, которые я настраиваю с помощью Picasso. Я использую recyclerview и всякий раз, когда появляется новый набор изображений, я вызываю adapter.notifyDataSetChanged(). Я загружаю первый набор - никаких проблем, для 2-го и 3-го уровней, когда вы делаете переоснащение, чтобы получить следующий набор и добавив существующий список и вызывающий - adapter.notifyDataSetChanged(). Для 3-го набора, когда я называю adapter.NotifyDataSetChanged() приложение падает с OutOfMemoryException

НО

Когда я загрузить все 3 набора 75 изображений, не возникло никаких проблем.

Код: Класс применения - где я строил Пикассо.

Picasso.Builder builder = new Picasso.Builder(this) 
      .memoryCache(new LruCache(24000)); 
    builder.downloader(new OkHttpDownloader(this,Integer.MAX_VALUE)); 
    Picasso built = builder.build(); 
    built.setLoggingEnabled(true); 

Пикассо Singleton Класс:

public class PicassoCache { 

/** 
* Static Picasso Instance 
*/ 
private static Picasso picassoInstance = null; 

/** 
* PicassoCache Constructor 
* 
* @param context application Context 
*/ 
private PicassoCache (Context context) { 

    Downloader downloader = new OkHttpDownloader(context, Integer.MAX_VALUE); 
    Picasso.Builder builder = new Picasso.Builder(context); 
    builder.downloader(downloader); 

    picassoInstance = builder.build(); 
} 

/** 
* Get Singleton Picasso Instance 
* 
* @param context application Context 
* @return Picasso instance 
*/ 
public static Picasso getPicassoInstance (Context context) { 

    if (picassoInstance == null) { 

     new PicassoCache(context); 
     return picassoInstance; 
    } 

    return picassoInstance; 
} 

} 

код, где я устанавливаю загрузки изображений с Пикассо /.

PicassoCache.getPicassoInstance(context).load(url).placeholder(R.mipmap.banner_placeholder).into(mView); 

Код, в котором я обновляю существующий список для загрузки при изменении набора данных.

Внутри Retorfit OnSuccess сообщение:

if (response.code() == 200) { 

List<CampaignCard> newCampaigns = response.body().getCampaigns(); 


for (int i = 0; i < newCampaigns.size(); i++) { 
    if (!campaignCards.contains(newCampaigns.get(i))) { 
     campaignCards.add(newCampaigns.get(i)); 
    } 
} 

dashBoardAdapter.notifyDataSetChanged(); 

} else if (response.code() == Params.CODE_422) { 
    Utils.ShowServiceErrorMessages(getActivity(), response); 
} else if (response.code() == Params.CODE_401) { 
    Utils.Logout(getActivity()); 
} 

адаптер Класс:

public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.DashboardViewHolder> implements View.OnClickListener { 


    private static final int VIEW_TYPE_CAMPAIGN = 1; 
    private static final int VIEW_TYPE_FEED = 2; 

    DashboardViewHolder holder; 


    protected List list; 
    protected int viewTypeLayout; 
    Context context; 
    int position; 

    Dashboard.DashboardActionList actionList; 
    Map<String, SourceContent> mPreviewLinkMapper; 
    ViewGroup parent; 

    //Picasso p; 
    public DashboardAdapter(List list, int viewTypeLayout) { 
     this.list = list; 
     this.viewTypeLayout = viewTypeLayout; 
    } 

    public DashboardAdapter(List list, int viewTypeLayout, Context context, Map<String, SourceContent> mPreviewLinkMapper) { 
     this.list = list; 
     this.viewTypeLayout = viewTypeLayout; 
     this.mPreviewLinkMapper = mPreviewLinkMapper; 
    } 

    @Override 
    public DashboardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     context = parent.getContext(); 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_feed, parent, false); 
     return new DashboardViewHolder(view, 2); 

    } 

    @Override 
    public void onBindViewHolder(DashboardViewHolder holder, final int position) { 
     BindFeedData(holder, position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public int getItemCount() { 
     return list.size(); 
    } 





    @SuppressWarnings("unchecked") 
    private void BindFeedData(DashboardViewHolder holder, int position) { 
     List<Feed> feeds = (List<Feed>) list; 
     if (holder.mBannerImage != null) { 
      if (feeds.get(position).getCampaign().getParticipation().getType().toLowerCase().contains("video")) { 

       holder.mPlayIcon.setVisibility(View.VISIBLE); 
       String url = feeds.get(position).getCampaign().getParticipation().getThumbnail_url(); 
       Utils.LoadImages(context, url, holder.mBannerImage, false); 

      } else if (feeds.get(position).getCampaign().getParticipation().getType().toLowerCase().contains("gif")) { 

       holder.mPlayIcon.setVisibility(View.GONE); 
       String url = feeds.get(position).getCampaign().getParticipation().getPost_file(); 
       Utils.loadGif(context, url, holder.mBannerImage); 

      } else if (feeds.get(position).getCampaign().getParticipation().getType().toLowerCase().contains("link") || 
        feeds.get(position).getCampaign().getParticipation().getType().toLowerCase().contains("youtube")) { 

       holder.mPlayIcon.setVisibility(View.GONE); 
       String slug = feeds.get(position).getCampaign().getSlug(); 
       List<String> images = mPreviewLinkMapper.get(slug).getImages(); 
       Utils.LoadImages(context, images.get(0), holder.mBannerImage, false); 

      } else { 
       holder.mPlayIcon.setVisibility(View.GONE); 
       holder.mBannerImage.setVisibility(View.VISIBLE); 
       String url = feeds.get(position).getCampaign().getParticipation().getPost_file(); 
       Utils.LoadImages(context, url, holder.mBannerImage, false); 
      } 
     } 

     if (holder.mBrandLogo != null) { 
      Utils.LoadImages(context, feeds.get(position).getInfluencer().getProfile_picture_url(), holder.mBrandLogo, true); 
     } 


     holder.mTitle.setText(feeds.get(position).getInfluencer().getName()); 
     holder.mSubTitle.setText(feeds.get(position).getCampaign().getName()); 
     holder.mTime.setText(feeds.get(position).getCampaign().getTimestamp()); 
     holder.mDescription.setText(feeds.get(position).getCampaign().getParticipation().getPost_content()); 
     holder.mEngagement.setText(feeds.get(position).getCampaign().getParticipation().getMetrics().getEngagements()); 
     holder.mImpresion.setText(feeds.get(position).getCampaign().getParticipation().getMetrics().getImpressions()); 
    } 



    } 


    public static class DashboardViewHolder extends RecyclerView.ViewHolder { 

     ImageView mBannerImage, mFacebook, mTwitter, mInstagram, mPlayIcon, mHotIcon, mLocationIcon; 
     CircularImageView mBrandLogo; 
     CustomTextViewRegular mDescription, mTime, mOption1, mOption2, mOption3; 
     CustomTextViewDemi mTitle, mSubTitle, mImpresion, mEngagement; 
     LinearLayout mDetailsLayout; 

     LinearLayout mOptionLayout1, mOptionLayout2, mOptionLayout3; 
     public ViewGroup dropPreview; 

     TableRow mTableOptions; 

     public DashboardViewHolder(View v, int viewtype) { 
      super(v); 
      InitFeedViews(v); 
      } 




     private void InitFeedViews(View v) { 
      mTitle = (CustomTextViewDemi) v.findViewById(R.id.adapterHeaderLayoutTitle); 
      mSubTitle = (CustomTextViewDemi) v.findViewById(R.id.adapterHeaderLayoutSubTitle); 
      mBrandLogo = (CircularImageView) v.findViewById(R.id.adapterHeaderLayoutLogo); 
      mTime = (CustomTextViewRegular) v.findViewById(R.id.adapterHeaderLayoutTime); 

      mBannerImage = (ImageView) v.findViewById(R.id.adapterFeedBannerImage); 
      mPlayIcon = (ImageView) v.findViewById(R.id.adapterFeedPlayIocn); 

      mImpresion = (CustomTextViewDemi) v.findViewById(R.id.adapterFeedImpressions); 
      mEngagement = (CustomTextViewDemi) v.findViewById(R.id.adapterFeedEngagements); 
      mDescription = (CustomTextViewRegular) v.findViewById(R.id.adapterFeedDescription); 

      dropPreview = (LinearLayout) v.findViewById(R.id.drop_preview); 
     } 

    } 

} 
+0

Используйте recycleview и изменить размер изображения при загрузке .. –

+0

@sunilsunny я использую recyclerview и изменение размера не работал. – MobDev

+0

поделиться своим кодом адаптера. В основном растровые изображения будут создавать OOM. Проблема может быть там. –

ответ

1

Вы бы столкнуться с "из памяти" вопросов много в случае библиотеки Picasso Я хотел бы предложить вам использовать Glide библиотека. У меня было много исключений из памяти, но все-таки, когда я использовал глиссирование, он работал хорошо.

Смежные вопросы