2

I am using ImageLoader class to load an image from an url and displaying it in a list view. But this ImageLoader is loading the image on an emulator, when I run my app on a real device it's not loading any image.(Just showing the default image).

Please tell me what I have to do with the ImageLoader class to get it working on a real device.

ImageLoader Class:

public class ImageLoader {

    MemoryCache memoryCache = new MemoryCache();
    FileCache fileCache;
    private Map<ImageView, String> imageViews = Collections
            .synchronizedMap(new WeakHashMap<ImageView, String>());
    ExecutorService executorService;
    // Handler to display images in UI thread
    Handler handler = new Handler();

    public ImageLoader(Context context) {
        fileCache = new FileCache(context);
        executorService = Executors.newFixedThreadPool(5);
    }

    final int stub_id = R.drawable.products;

    public void DisplayImage(String url, ImageView imageView) {
        imageViews.put(imageView, url);
        Bitmap bitmap = memoryCache.get(url);
        if (bitmap != null)
            imageView.setImageBitmap(bitmap);
        else {
            queuePhoto(url, imageView);
            imageView.setImageResource(stub_id);
        }
    }

    private void queuePhoto(String url, ImageView imageView) {
        PhotoToLoad p = new PhotoToLoad(url, imageView);
        executorService.submit(new PhotosLoader(p));
    }

    private Bitmap getBitmap(String url) {
        File f = fileCache.getFile(url);

        Bitmap b = decodeFile(f);
        if (b != null)
            return b;

        // Download Images from the Internet
        try {
            Bitmap bitmap = null;
            URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) imageUrl
                    .openConnection();
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            conn.setInstanceFollowRedirects(true);
            InputStream is = conn.getInputStream();
            OutputStream os = new FileOutputStream(f);
            Utils.CopyStream(is, os);
            os.close();
            conn.disconnect();
            bitmap = decodeFile(f);
            return bitmap;
        } catch (Throwable ex) {
            ex.printStackTrace();
            if (ex instanceof OutOfMemoryError)
                memoryCache.clear();
            return null;
        }
    }

    // Decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f) {
        try {
            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            FileInputStream stream1 = new FileInputStream(f);
            BitmapFactory.decodeStream(stream1, null, o);
            stream1.close();

            // Find the correct scale value. It should be the power of 2.
            // Recommended Size 512
            final int REQUIRED_SIZE = 70;
            int width_tmp = o.outWidth, height_tmp = o.outHeight;
            int scale = 1;
            while (true) {
                if (width_tmp / 2 < REQUIRED_SIZE
                        || height_tmp / 2 < REQUIRED_SIZE)
                    break;
                width_tmp /= 2;
                height_tmp /= 2;
                scale *= 2;
            }

            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            FileInputStream stream2 = new FileInputStream(f);
            Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2);
            stream2.close();
            return bitmap;
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    // Task for the queue
    private class PhotoToLoad {
        public String url;
        public ImageView imageView;

        public PhotoToLoad(String u, ImageView i) {
            url = u;
            imageView = i;
        }
    }

    class PhotosLoader implements Runnable {
        PhotoToLoad photoToLoad;

        PhotosLoader(PhotoToLoad photoToLoad) {
            this.photoToLoad = photoToLoad;
        }

        @Override
        public void run() {
            try {
                if (imageViewReused(photoToLoad))
                    return;
                Bitmap bmp = getBitmap(photoToLoad.url);
                memoryCache.put(photoToLoad.url, bmp);
                if (imageViewReused(photoToLoad))
                    return;
                BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
                handler.post(bd);
            } catch (Throwable th) {
                th.printStackTrace();
            }
        }
    }

    boolean imageViewReused(PhotoToLoad photoToLoad) {
        String tag = imageViews.get(photoToLoad.imageView);
        if (tag == null || !tag.equals(photoToLoad.url))
            return true;
        return false;
    }

    // Used to display bitmap in the UI thread
    class BitmapDisplayer implements Runnable {
        Bitmap bitmap;
        PhotoToLoad photoToLoad;

        public BitmapDisplayer(Bitmap b, PhotoToLoad p) {
            bitmap = b;
            photoToLoad = p;
        }

        public void run() {
            if (imageViewReused(photoToLoad))
                return;
            if (bitmap != null)
                photoToLoad.imageView.setImageBitmap(bitmap);
            else
                photoToLoad.imageView.setImageResource(stub_id);
        }
    }

    public void clearCache() {
        memoryCache.clear();
        fileCache.clear();
    }

}

My GalleryTab Class:--

public class GalleryTab extends Fragment {
    GridView gridview;
    ProgressDialog mProgressDialog;
    GridViewAdapter adapter;
    public List<GalleryList> phonearraylist = null;
    View view;
    private WeakReference<RemoteDataTask> asyncTaskWeakRef;

    public static Fragment newInstance(Context context) {
        GalleryTab f = new GalleryTab();
        return f;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        view = inflater.inflate(R.layout.activity_gallery_tab, null);
        gridview = (GridView) view.findViewById(R.id.gridview);
        setRetainInstance(true);
        startNewAsyncTask();
        // new RemoteDataTask(this).execute();
        return view;
    }

    // RemoteDataTask AsyncTask
    private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
        private WeakReference<GalleryTab> fragmentWeakRef;

        private RemoteDataTask(GalleryTab gallerytab) {
            this.fragmentWeakRef = new WeakReference<GalleryTab>(gallerytab);
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mProgressDialog = new ProgressDialog(getActivity());
            mProgressDialog.setTitle("Gallery");
            mProgressDialog.setMessage("Loading...");
            mProgressDialog.setIndeterminate(false);
            mProgressDialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            // Create the array

            phonearraylist = new ArrayList<GalleryList>();
            try {
                for (int i = 0; i <= 6; i++) {
                    GalleryList map = new GalleryList();
                    map.setGallery("http://oi39.tinypic.com/21oydxs.jpg");
                    // System.out.println("PRINT!!!!--  "+ i);
                    phonearraylist.add(map);
                }
            } catch (ParseException e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            // if (this.fragmentWeakRef.get() != null) {
            adapter = new GridViewAdapter(getActivity(), phonearraylist);
            // System.out.println("PRINT SIZE --  "+ phonearraylist.size());
            gridview.setAdapter(adapter);

            mProgressDialog.dismiss();
            // }
        }
    }

    private void startNewAsyncTask() {
        RemoteDataTask asyncTask = new RemoteDataTask(this);
        this.asyncTaskWeakRef = new WeakReference<RemoteDataTask>(asyncTask);
        asyncTask.execute();
    }
}

My GridViewAdapter Class:-

public class GridViewAdapter extends BaseAdapter {

    // Declare Variables
    Context context;
    LayoutInflater inflater;
    ImageLoader imageLoader;
    private List<GalleryList> galleryArraylist = null;
    private ArrayList<GalleryList> arraylist;

    public GridViewAdapter(Context context, List<GalleryList> phonearraylist) {
        this.context = context;
        this.galleryArraylist = phonearraylist;
        inflater = LayoutInflater.from(context);
        this.arraylist = new ArrayList<GalleryList>();
        this.arraylist.addAll(phonearraylist);
        imageLoader = new ImageLoader(context);
    }

    public class ViewHolder {
        ImageView phone;
    }

    @Override
    public int getCount() {
        return galleryArraylist.size();
    }

    @Override
    public Object getItem(int position) {
        return galleryArraylist.get(position);
    }

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

    public View getView(final int position, View view, ViewGroup parent) {
        final ViewHolder holder;
        if (view == null) {
            holder = new ViewHolder();
            view = inflater.inflate(R.layout.gridview_item, null);
            // Locate the ImageView in gridview_item.xml
            holder.phone = (ImageView) view.findViewById(R.id.phone);
            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }
        // Set the results into ImageView
        imageLoader.DisplayImage(galleryArraylist.get(position).getGallery(),
                holder.phone);
        // Listen for GridView Item Click
        view.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // Send single item click data to SingleItemView Class
                Intent intent = new Intent(context, SingleItemView.class);
                // Pass all data phone
                intent.putExtra("gallery",
                        (galleryArraylist.get(position).getGallery()));
                // Start SingleItemView Class
                context.startActivity(intent);
            }
        });
        return view;
    }
}
Vijay Laxmi
  • 165
  • 1
  • 21

4 Answers4

3

Check necessary permissions in the manifest .

keybee
  • 1,498
  • 20
  • 32
  • i have already added that and its working but its really slow...do you have any solution to fast the process..please check the edited classes – Vijay Laxmi Aug 24 '13 at 08:47
  • Dou you really need to download the images at launch time? Is the data changing that often? You could just set up for example a daily update, and save images on the device. I would do the following: download data at the first launch, and then check every launch if update is needed. Download a version number from your url and store it and increase the version number every time you want the apk to download everything again. On the device if storedversion is lower than version on url then update, if not, load saved images. – keybee Aug 24 '13 at 09:44
0

If the app displays default image, then the following line of code is executing:

photoToLoad.imageView.setImageBitmap(stub_id);

That means that your bitmap is null. Use debug to find out why null-bitmap is passed to the constructor of BitmapDisplayer.

Dmytro Titov
  • 2,802
  • 6
  • 38
  • 60
0

I can recommend a different way that works like a charm: Android Query.

You can download that jar file from here

AQuery androidAQuery=new AQuery(this);

As an example:

androidAQuery.id(YOUR IMAGEVIEW).image(YOUR IMAGE TO LOAD, true, true, getDeviceWidth(), ANY DEFAULT IMAGE YOU WANT TO SHOW);

It's very fast and accurate, and using this you can find many more features like Animation when loading; getting a bitmap, if needed; etc.

Pratik Dasa
  • 7,439
  • 4
  • 30
  • 44
0

Add this Permission in your manifest file

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Mukesh Y
  • 762
  • 6
  • 16