My Problem at Cache Chalenge

Hi Friends
1.first i have to ask a question
i dont understand this bit of code that i have bold it

public void queueThumbnail(T target , String url) {
Log.i(TAG,"Got a URL: " + url);
if (url == null) {
mRequestMap.remove(target);
} else {
mRequestMap.put(target,url);
mRequestHandler.obtainMessage(MESSAGE_DOWNLOAD,target).sendToTarget();

    }

}

2.second i have a problem with my code . when i launch app everthing is good and images will be displayed and when i rotate the screen down also everthing is Okay and newer images will be downloaded and displayed but that time when i rotate back up to see cached images then previous images wil be replaced by new images :expressionless: and thats where my problem is

following is my code

PhotoGalleryFragment.java

public class PhotoGalleryFragment extends Fragment {

    private static final String TAG = "PhotoGalleryFragment";

    private RecyclerView mPhotoRecyclerView;
    List<GalleryItem> mItems = new ArrayList<>();
    private boolean mLoading;
    private int page;
    private int round = 3;
    int round2;
    private PhotoAdapter mAdapter;
    private boolean iAmLoading;
    private ThumbnailDownloader<PhotoHolder> mThumbnailDownloader;

    public static PhotoGalleryFragment newInstance() {
        return new PhotoGalleryFragment();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
        page = 1;
        new FetchItemsTask().execute(page);

        Handler responseHandler = new Handler();
        mThumbnailDownloader = new ThumbnailDownloader<>(responseHandler);
        mThumbnailDownloader.setThumbnailDownloadListener(new ThumbnailDownloader.ThumbnailDownloadListener<PhotoHolder>() {

            @Override
            public void onThumbnailDownloaded(PhotoHolder target, Bitmap thumbnail) {
                Drawable drawable = new BitmapDrawable(getResources(),thumbnail);
                target.bindDrawable(drawable);
            }
        });
        mThumbnailDownloader.start();
        mThumbnailDownloader.getLooper();
    }

    @Nullable
    @Override
    public View onCreateView(final LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_photo_gallery,container,false);


        mPhotoRecyclerView = (RecyclerView) v.findViewById(R.id.photo_recycler_view);
        mPhotoRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                mLoading = false;
                float columnWidthContant = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,140,getActivity().getResources().getDisplayMetrics());
                float itemHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,120,getActivity().getResources().getDisplayMetrics());
                int widthScreen = mPhotoRecyclerView.getWidth();
                int heightScreen = mPhotoRecyclerView.getHeight();

                float sum = widthScreen/columnWidthContant;
                float sum2 =heightScreen/itemHeight;

                round =(int) Math.round(sum);
                round2 = (int) sum2;




                Log.i("MONITOR",columnWidthContant + " " +  widthScreen + " " + sum + " " + round);
                Log.i("MONITOR2",itemHeight + " " + heightScreen + " " + sum2 + " " + round2);

                mPhotoRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(),round));
                setupAdapter();

                mPhotoRecyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });

        mPhotoRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(),round));
        mAdapter = new PhotoAdapter(mItems);
        mPhotoRecyclerView.setAdapter(mAdapter);

        mLoading = true;


        mPhotoRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                if (mLoading) {
                    return;
                }
                GridLayoutManager layoutManager =(GridLayoutManager) mPhotoRecyclerView.getLayoutManager();
                int visibleItemCount = layoutManager.getChildCount();
                int totalItemCount = layoutManager.getItemCount();
                int pastVisibleItems = layoutManager.findFirstVisibleItemPosition();


                //Log.d("FIRSTER",pastVisibleItems + " " +(pastVisibleItems % 100) + " Here");
                if (pastVisibleItems + visibleItemCount >= totalItemCount) {
                    Log.i("PAGERV1",page + " here");

                    if (iAmLoading) {
                        return;
                    }

                    page++;

                    if (page > 10) {
                        page = 1;
                    }

                    iAmLoading = true;
                    new FetchItemsTask().execute(page);

                }
            }
        });

        return v;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mThumbnailDownloader.quit();
        Log.i(TAG,"Background thread destroyed");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mThumbnailDownloader.clearQueue();
    }

    private void setupAdapter() {

        Log.d("STARTER",page + " Here");

       if (isAdded()) {
           if (mItems.size() == 0 ) {
               mAdapter = new PhotoAdapter(mItems);
               mPhotoRecyclerView.setAdapter(mAdapter);
           }
           if (page <= 10 && mItems.size() != 0) {            
               mAdapter.notifyDataSetChanged();
           }
        }
    }


    private class PhotoHolder extends RecyclerView.ViewHolder {

        private ImageView mItemImageView;

        public PhotoHolder(View itemView) {
            super(itemView);
            mItemImageView = (ImageView) itemView.findViewById(R.id.item_image_view);
        }

        public void bindDrawable(Drawable drawable) {
            
            mItemImageView.setImageDrawable(drawable);
        }
    }

    private class PhotoAdapter extends RecyclerView.Adapter<PhotoHolder> {


        private List<GalleryItem> mGalleryItems;


        public PhotoAdapter(List<GalleryItem> galleryItems) {
            mGalleryItems = galleryItems;
        }

        @Override
        public PhotoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(getActivity());
            View v = inflater.inflate(R.layout.list_item_gallery,parent,false);
            return new PhotoHolder(v);

        }

        @Override
        public void onBindViewHolder(PhotoHolder holder, int position) {
            GalleryItem galleryItem = mGalleryItems.get(position);
            Bitmap bitmap = mThumbnailDownloader.loadDrawables(galleryItem.getUrl());

            if (bitmap == null) {
                Drawable placeHolder = getResources().getDrawable(R.drawable.bill_up_close);
                holder.bindDrawable(placeHolder);
                mThumbnailDownloader.queueThumbnail(holder,galleryItem.getUrl());
            } else {
                holder.bindDrawable(new BitmapDrawable(getResources(),bitmap));
            }
        }

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

        public void notifyDataHasChanged(List<GalleryItem> items) {
            mGalleryItems = items;
            mAdapter.notifyDataSetChanged();

        }
    }


    private class  FetchItemsTask extends AsyncTask<Integer,Void,List<GalleryItem>> {

        private ProgressDialog dialog;


        @Override
        protected void onPreExecute() {
            if (isAdded()) {
                dialog = new ProgressDialog(getActivity());
                dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
                getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
                if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                    getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                } else  {
                    getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                }
                dialog.setMessage("Processing...");
                dialog.show();
            }

        }

        @Override
        protected List<GalleryItem> doInBackground(Integer... params) {
            int page = params[0];
            return new FlickrFetcher().fetchItems(page);
        }


        @Override
        protected void onPostExecute(List<GalleryItem> galleryItems) {
            if (isAdded()) {
                dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
                getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
                getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
                dialog.dismiss();
                iAmLoading = false;
                if (mItems.size() == 0) {
                    mItems.addAll(galleryItems);
                    setupAdapter();
                } else {
                    final int lastPosition = mItems.size();
                    mItems.addAll(galleryItems);
                    mPhotoRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                        @Override
                        public void onGlobalLayout() {
                            mPhotoRecyclerView.smoothScrollToPosition(lastPosition + (round*round2));
                            mPhotoRecyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        }
                    });
                    setupAdapter();
                }
            }


        }
    }
}

ThumbnailDownloader.java

public class ThumbnailDownloader<T> extends HandlerThread {
    private static final String TAG = "ThumbnailDownloader";
    private static final int MESSAGE_DOWNLOAD = 0;

    private boolean mHasQuit = false;
    private Handler mRequestHandler;
    private ConcurrentHashMap<T,String> mRequestMap = new ConcurrentHashMap<>();
    private Handler mResponseHandler;
    private ThumbnailDownloadListener<T> mThumbnailDownloadListener;
    //private Integer mPosition;
    private LruCache<String,Bitmap> mBitmapsMemCache;

    public interface ThumbnailDownloadListener<T> {
        void onThumbnailDownloaded(T target,Bitmap thumbnail);
    }

    public void setThumbnailDownloadListener(ThumbnailDownloadListener listener) {
        mThumbnailDownloadListener = listener;
    }

    public ThumbnailDownloader(Handler responseHandler) {
        super(TAG);
        mResponseHandler = responseHandler;
        mBitmapsMemCache = new LruCache<String,Bitmap>(((int)Runtime.getRuntime().maxMemory()/1024)/8);
    }

    @Override
    public boolean quit() {
        mHasQuit = true;
        return super.quit();
    }

    public Bitmap loadDrawables(String url) {
        Bitmap bitmap = mBitmapsMemCache.get(url);
        return bitmap;

    }


    public void queueThumbnail(T target , String url) {

        Log.i(TAG,"Got a URL: " + url);
        if (url == null) {
            mRequestMap.remove(target);
        } else {
            mRequestMap.put(target,url);
            mRequestHandler.obtainMessage(MESSAGE_DOWNLOAD,target).sendToTarget();

        }

    }

    @Override
    protected void onLooperPrepared() {
        
        mRequestHandler = new Handler() {

            @Override
            public void handleMessage(Message msg) {

                if (msg.what == MESSAGE_DOWNLOAD) {
                    T target = (T) msg.obj;
                    Log.i(TAG,"Got a request for URL: "  + mRequestMap.get(target));
                    handleRequest(target);
                }
            }
        };
    }

    private void handleRequest(final T target) {
            final String url = mRequestMap.get(target);
            final Bitmap bitmap;

            if (url == null) {
                return;
            }

            bitmap = downloadBitmap(url);

            //mBitmapsMemCache.put(url,bitmap);


            Log.i(TAG,"Bitmap created");

            mResponseHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (mRequestMap.get(target) != url) {
                        return;
                    }
                    mRequestMap.remove(target);
                    mThumbnailDownloadListener.onThumbnailDownloaded(target,bitmap);
                }
            });

    }

    private Bitmap downloadBitmap(String url) {
        if (url == null) {
            return null;
        }

        Bitmap bitmap = mBitmapsMemCache.get(url);

        if (bitmap != null) {
            return bitmap;
        }

        try {
            byte[] bitmapBytes = new FlickrFetcher().getUrlBytes(url);
            bitmap = BitmapFactory.decodeByteArray(bitmapBytes,0,bitmapBytes.length);
            mBitmapsMemCache.put(url,bitmap);
            return bitmap;
        } catch (IOException ioe) {
            Log.e(TAG,"Cannot download the image ",ioe);
            return null;
        }
    }

    public void clearQueue() {
        mRequestHandler.removeMessages(MESSAGE_DOWNLOAD);
        mBitmapsMemCache.evictAll();
        mRequestMap.clear();
    }
}

Hi FastlyNima

For the 1st question, if the url is not a valid string, the related PhotoHolder object key/value pair will be removed from the mRequestMap.

For the 2nd question, since there are lots of new pictures uploaded to the Flickr during one second, the old ones cached in the app will be flushed by the new ones during each rotation action. However, when you add the search function in the Chapter 27, the low rate of uploading pictures for a specified query string will make the cache function more useful.