ilansas
ilansas

Reputation: 6099

Images and listviews (Asynchronous)

I have a Listview which will contain for each item a different image. I followed this tutorial which explain how to implement the all things.

When testing my app, I see that every item at the same time, display each image for few milliseconds and do it a lot of times which make my app crash. I can't see where I'm wrong. Here is my code :

ShowItemAdapter.java

public class ShowItemsAdapter extends ArrayAdapter<Show> {

    private ArrayList<Show> shows;
    private Context context;
    private LayoutInflater inflater;

    public class ViewHolder{
        public TextView title;
        public ImageView image;
    }

    public ShowItemsAdapter(Context context, List<Show> showArray, List<Bitmap> images)
    {
        super(context, R.layout.item_shows, showArray);
        shows = (ArrayList) showArray;
        this.context = context;
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    }

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

        View rootView = convertView;
        ViewHolder holder;

        if(convertView == null)
        {
            rootView = inflater.inflate(R.layout.item_shows, parent, false);
        }

        holder = new ViewHolder();
        holder.image = (ImageView) rootView.findViewById(R.id.item_shows_image);
        holder.title = (TextView) rootView.findViewById(R.id.item_shows_title);

        holder.title.setText(shows.get(position).getTitle());

        ImageFactory imageFactory = new ImageFactory();
        imageFactory.setParameters(context, shows.get(position).getImageURL(), holder.image);
        return rootView;
    }

ImageFactory.java

public class ImageFactory {

    public static final String IMAGE = "IMAGE";

    private ReceiveImageService receiveImageService;
    private Intent intentService;
    private ImageReceivedConfirmerReceiver imageReceivedConfirmerReceiver = new ImageReceivedConfirmerReceiver();
    private Bitmap image;
    private ImageView imageView;
    private String url;
    private Context context;

    public ImageFactory(){}

    public void setParameters(Context context, String url, ImageView imageView)
    {
        this.context = context;
        this.imageView = imageView;
        context.registerReceiver(
                imageReceivedConfirmerReceiver,
                new IntentFilter(ImageFactory.IMAGE)
        );

        this.url = url;

        //Creation of the service and adding request
        intentService = new Intent(context, ReceiveImageService.class);
        intentService.putExtra("URL", url);
        context.startService(intentService);
        context.bindService(intentService, receiveImageServiceConnection, Context.BIND_AUTO_CREATE);
    }

    private void displayImage(){
        imageView.setImageBitmap(image);
    }

    private ServiceConnection receiveImageServiceConnection = new ServiceConnection(){

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            ReceiveImageService.ReceiveImageBinder binder = (ReceiveImageService.ReceiveImageBinder)service;
            //get service
            receiveImageService = binder.getService();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };

    private class ImageReceivedConfirmerReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if(receiveImageService != null)
            {
                //Receive the array of data
                image = receiveImageService.getImage();
                displayImage();
            }
        }
    }
}

ReceiveImageService.java

public class ReceiveImageService extends IntentService {

    private Connection connectionToServer;
    private final IBinder receiveImageBinder = new ReceiveImageBinder();

    private final static String BASE_URL = "http://www.readyo.linux.efrei.fr/";

    private Bitmap image;

    public ReceiveImageService(){super("ReceiveImageService");}

    @Override
    protected void onHandleIntent(Intent intent) {
        String URL = BASE_URL + intent.getStringExtra("URL");
        image = reachData(URL);
        sendFinishAlert();
    }

    private Bitmap reachData(String URL) {
        HttpURLConnection urlConnection = null;
        try {
            URL url = new URL(URL);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setUseCaches(true);
            urlConnection.addRequestProperty("Cache-Control", "max-age=0");
            // handle issues
            if (urlConnection.getResponseCode() != 200) {
                throw new Exception("Status Error CODE : " + urlConnection.getResponseCode());
            }

            InputStream in = new BufferedInputStream(urlConnection.getInputStream());
            Bitmap bitmap = BitmapFactory.decodeStream(in);
            return bitmap;
        }catch (Exception e)
        {
            if(BuildConfig.DEBUG) Log.e("DEBUG", e.getMessage());

            //On notifie l'activité qu'une erreur de connexion a eu lieu
            //sendBroadcast(new Intent(AbstractNavigationFragment.ERROR_ACTION));
        }
        finally {
            if(urlConnection != null)
            urlConnection.disconnect();
        }
        return null;
    }

    protected void sendFinishAlert() {
        Intent intent = new Intent(ImageFactory.IMAGE);
        sendBroadcast(intent);
    }

    public Bitmap getImage()
    {
        return image;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent,flags,startId);
    }

    //BINDER
    private ReceiveImageService getInstance()
    {
        return this;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return receiveImageBinder;
    }

    @Override
    public boolean onUnbind(Intent intent){
        return false;
    }

    public class ReceiveImageBinder extends Binder {
        public ReceiveImageService getService() {
            return ReceiveImageService.this;
        }
    }
}

Upvotes: 0

Views: 110

Answers (2)

joselufo
joselufo

Reputation: 3415

The best for do that is use libraries because you can have a lot of problems with memory leaks.

The best library for load images is Picasso and Glide.

Picasso example:

Picasso.with(context).load("URL").into(imageView);

Glide example:

Glide.with(context).load("url").into(imageView);

Upvotes: 1

Andrey  Kopeyko
Andrey Kopeyko

Reputation: 1566

Look into logcat - the crash reason is described there.

Post it here, if you'll have more questions.

Upvotes: 0

Related Questions