Pregunta

Tengo el siguiente código que se ejecuta en el dispositivo Android. Funciona muy bien y muestra mi lista de artículos maravillosamente. También es inteligente en el hecho de que sólo descarga los datos cuando sea necesario por el ArrayAdapter. Sin embargo, mientras que la descarga de la miniatura está ocurriendo, la totalidad de los puestos de la lista y no se puede desplazar hasta que sea terminada la descarga. ¿Hay alguna manera de enhebrar por lo que va siendo desplazamiento felices, quizás muestra un marcador de posición para la imagen de la descarga, terminar la descarga, y luego mostrar?

creo que sólo tiene que poner mi clase downloadImage en su propio hilo para su ejecución por separado de la interfaz de usuario. Pero cómo agregar esto en mi código es el misterio!

Cualquier ayuda con esto sería muy apreciada.

private class CatalogAdapter extends ArrayAdapter<SingleQueueResult> {

    private ArrayList<SingleQueueResult> items;

    //Must research what this actually does!
    public CatalogAdapter(Context context, int textViewResourceId, ArrayList<SingleQueueResult> items) {
        super(context, textViewResourceId, items);
        this.items = items;

    }

    /** This overrides the getview of the ArrayAdapter. It should send back our new custom rows for the list */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View v = convertView;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.mylists_rows, null);

        }
        final SingleQueueResult result = items.get(position);
        // Sets the text inside the rows as they are scrolled by!
        if (result != null) {

            TextView title = (TextView)v.findViewById(R.id.mylist_title);
            TextView format = (TextView)v.findViewById(R.id.mylist_format);
            title.setText(result.getTitle());
            format.setText(result.getThumbnail());

            // Download Images
            ImageView myImageView = (ImageView)v.findViewById(R.id.mylist_thumbnail);
            downloadImage(result.getThumbnail(), myImageView);

        }

        return v;
    }
}

// This should run in a seperate thread
public void downloadImage(String imageUrl, ImageView myImageView) {

    try {
        url = new URL(imageUrl);
        URLConnection conn = url.openConnection();
        conn.connect();
        InputStream is = conn.getInputStream();
        BufferedInputStream bis = new BufferedInputStream(is);
        Bitmap bm = BitmapFactory.decodeStream(bis);
        bis.close();
        is.close();
        myImageView.setImageBitmap(bm);
    } catch (IOException e) {
        /* Reset to Default image on any error. */
        //this.myImageView.setImageDrawable(getResources().getDrawable(R.drawable.default));
    }
}
¿Fue útil?

Solución

Aquí hay una versión simplificada de lo que estoy usando en mis aplicaciones:

// this lives in Application subclass and is reused
public static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();

// the method itself

    public void attachImage(final String fileUrl, final ImageView view) {
        EXECUTOR.execute(new Runnable() {

            @Override
            public void run() {
                final Drawable image = methodThatGetsTheImage(fileUrl);
                if (image != null) {
                    view.post(new Runnable() {

                        @Override
                        public void run() {
                            view.setImageDrawable(drawable);
                        }
                    });
                }
            }
        });
    }

Otros consejos

También puede revisar CWAC-miniatura por una caída en solución (aunque tiene un poco más sobrecarga que las soluciones más simples arriba). Lo he utilizado con gran éxito casi en cualquier lugar que tengo una imagen web para descargar; que, básicamente, configurar algunas opciones de caché globales para su aplicación, a continuación, sólo envolver su ListAdapter en un ThumbnailAdapter con una lista de android: id de los imageviews en su lista, y llamar setTag (imageUrl) en los imageviews en el método getView de su adaptador, y que se encarga del resto.

Sí. Debe evitar que se ejecuta en el hilo de interfaz de usuario tanto como sea posible. Cuando estás en getView () que está en el hilo de interfaz de usuario. Para salir haga lo siguiente:

new Thread(new Runnable(){

  public void run() {
    // your code here

  }}).start();

A continuación, cuando se tiene que modificar una vista en algunas volver ir sobre la rosca del interfaz de usuario de la siguiente manera:

runOnUiThread(new Runnable(){

  public void run() {
    // your view-modifying code here

  }});

.. o utilizar el mecanismo de View.post ().

En el ejemplo de lo que sucederá es que el elemento se mostrará en la pantalla antes de que la imagen se encuentra disponible para su visualización. Se sugiere emplear una ruleta 'carga' o algún otro marcador de posición para indicar al usuario lo que está sucediendo.

Usted puede, en la práctica nido como esto varias veces, aunque se llega a un punto en un diseño simplificado está en orden. clases anónimas pueden ser memoria en cuanto ineficiente y disparar una gran cantidad de hilos sin cancelar mecanismo puede tener sus propios inconvenientes.

Se puede experimentar algunas dificultades como un efecto secundario de la modificación de vistas después de getView () ha salido. Algunos puntos de vista pueden necesitar invalidate () llama a tener sus cambios surtan efecto. También tenga cuidado si usted está reciclando vistas en su getView (), debe asegurarse de que en el momento en que se ejecuta el código de la vista que altera la vista todavía se utiliza para el contenido que se está solicitando. setTag () / getTag () es útil para almacenar una identificación de los datos que más tarde puede comprobar para asegurarse de que su vista no ha sido reciclado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top