2015-01-18 3 views
0

У меня есть Listview, который будет содержать для каждого элемента другое изображение. Я последовал за этим tutorial, которые объясняют, как реализовать все вещи.Images and listviews (Asynchronous)

При тестировании моего приложения я вижу, что каждый элемент одновременно отображает каждое изображение за несколько миллисекунд и делает это много раз, из-за чего мое приложение падает. Я не вижу, где я ошибаюсь. Вот мой код:

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; 
     } 
    } 
} 

ответ

1

Лучше всего использовать библиотеки, потому что у вас может быть много проблем с утечками памяти.

Лучшая библиотека для изображений нагрузки - Picasso и Glide.

Пикассо пример:

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

Glide пример:

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

Да, я слышал об этих двух, я на самом деле пытался это сделать с нуля, чтобы понять механизмы и узнать ... Хорошо спасибо в любом случае – ilansas

0

Посмотрите на logcat - там описывается причина сбоя.

Отправьте его здесь, если у вас появятся дополнительные вопросы.

+0

На самом деле я действительно не имеют каких-либо ошибок, аварии, LogCat просто говорит мне, в конце концов, что много памяти, а затем мой телефон начинает сильно задерживаться (в основном из-за количества загруженных изображений). – ilansas

+0

Вы написали - «... которые заставляют мое приложение сбой». Вы ошиблись? –

+0

Вы правы, я хотел сказать, что мое приложение рушится из-за утечки памяти из-за бесконечного отображения изображений. Извините, если я не был ясен – ilansas