Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Volley NetworkImageView worke offline

I use Volley NetworkImageView to download images from internet and show in my listview. Now I want to make Volley NetworkImageView show saved images when there is no network available. Volley has already cached images by URL as a key because when I use

Entry entry = SingletonRequestQueue.getInstance(context).getRequestQueue().getCache().get(imageURL);

the entry.data is not null. But my problem is that image resolutions are high and I can not use

Bitmap b = BitmapFactory.decodeByteArray(entry.data, 0, entry.data.length);

because it creates a lot of lag and I have to reinvent the wheel because again I must create asynctask see when listview has scrolled to cancel decoding, recycling the bitmap, creating in memory cache, finding best insample value and ...

so better Idea is just do some tricks that make Volley NetworkImageView use its own DiskLRUCache to show them when there is no network.

Any idea?

My code:

public class SingletonRequestQueue {


    private static SingletonRequestQueue mInstance;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private static Context mCtx;
    private LruBitmapCache mLruBitmapCache;

    private SingletonRequestQueue(Context context) {
        mCtx = context;
        mRequestQueue = getRequestQueue();
        mLruBitmapCache = new LruBitmapCache(LruBitmapCache.getCacheSize(context));
        mImageLoader = new ImageLoader(mRequestQueue,mLruBitmapCache);

    }

    public static synchronized SingletonRequestQueue getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new SingletonRequestQueue(context);
        }
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {

            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.

            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext(),new OkHttpStack());
//          mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    } 

    public ImageLoader getImageLoader() {
        return mImageLoader;
    }

    public LruBitmapCache getLruBitmapCache() {
        return mLruBitmapCache;
    }

    public void setLruBitmapCache(LruBitmapCache lruBitmapCache) {
        mLruBitmapCache = lruBitmapCache;
    }


}

and in my adapter:

public IssueListAdapter(Context context, int resource, List<Issue> objects) {
        super(context, resource, objects);
        this.context = context;
        this.mIssueList = objects;
        mImageLoader = SingletonRequestQueue.getInstance(context).getImageLoader();
}

public static class ViewHolder{

    public  NetworkImageView mNetworkImageView;
    public  TextView mFee;
    public  TextView mName;
}


@Override
public View getView(int position, View convertView, ViewGroup parent) {


    ViewHolder holder;

    if(convertView == null){
        holder = new ViewHolder();
        LayoutInflater inflater =    
                (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.gridview_issuelist_item, parent, false);

        holder.mNetworkImageView = (NetworkImageView)convertView.findViewById(R.id.NetworkImageView_MainActivity_issue_image);
        holder.mName = (TextView)convertView.findViewById(R.id.TextView_MainActivity_name);
        holder.mFee = (TextView)convertView.findViewById(R.id.TextView_MainActivity_fee);
        Utility.settingTypfaceFont(context, holder.mName);
        Utility.settingTypfaceFont(context, holder.mFee);

        convertView.setTag(holder);

    }else{
        holder = (ViewHolder)(convertView.getTag());
    }

    final Issue issue = mIssueList.get(position);
    holder.mName.setText(issue.getTitle());
    holder.mFee.setText(String.valueOf(issue.getFee()));
    String imageURL = issue.getPublicCover();

    holder.mNetworkImageView.setImageUrl(imageURL, mImageLoader);
    holder.mNetworkImageView.setDefaultImageResId(R.drawable.placeholder2);;

    /*
    Entry entry = SingletonRequestQueue.getInstance(context).getRequestQueue().getCache().get(imageURL);
    if(entry != null && entry.data != null){
        byte[] imageByte = entry.data;
        loadBitmap(imageByte, holder.mNetworkImageView,imageURL);
    }else{
        holder.mNetworkImageView.setImageUrl(imageURL, mImageLoader);
    }*/

    return convertView;
}

@Override
public int getCount() {
    if(mIssueList != null){
        return mIssueList.size();           
    }
    else{
        return 0;
    }
}

public List<Issue> getIssueList() {
    return mIssueList;
}

}
like image 255
mmlooloo Avatar asked Feb 11 '23 17:02

mmlooloo


2 Answers

I prefer to use Volley/retrofit with Android-Universal-Image-Loader /Picasso, picture loader libs have done a great job in loading and caching images indeed.

They handle everything with a single line of code by default:

Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);

Also you can animate, resize your images and add placeholder while they loading.

like image 110
M. Reza Nasirloo Avatar answered Feb 23 '23 11:02

M. Reza Nasirloo


Just add this line in BasicNetwork class

if (!ConnectivityUtils.isNetworkEnabled(CardApplication.getContext()) && request instanceof ImageRequest) {
            VolleyLog.e("Cached response", "No Network Connectivity for Url=", request.getUrl());
            return new NetworkResponse(HttpStatus.SC_NOT_MODIFIED,
                    request.getCacheEntry().data, responseHeaders, true);
        }

and for data request expiry you can change the Cached.Entry using using own HttpHeaderParser

Here is Link which explain thing in detail

like image 41
Vipin Sahu Avatar answered Feb 23 '23 13:02

Vipin Sahu