0

我的問題是,我有一個RecyclerView,並在此我加載音樂專輯的相冊藝術,圖像加載完美,但加載是線性的,因此,當緩慢拖動RecyclerView時,工作正常,但是當我快速拖動RecyclerView時,圖像的加載花費了很多時間。 我使用一個AsyncTask,但我不明白爲什麼線程一個一個地線性運行。RecyclerView非線性加載圖像

這是創建和綁定我ViewHolder

@Override 
public AdaptadorAlbumes.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View v = LayoutInflater.from(parent.getContext()) 
      .inflate(R.layout.item_album, parent, false); 
    ViewHolder vh = new ViewHolder(v, actividad); 
    return vh; 
} 

@Override 
public void onBindViewHolder(ViewHolder holder, int position) { 
    cursor.moveToPosition(position); 
    holder.imgVwPortada.setImageBitmap(Datos.getPortadaDefault()); 
    holder.imgVwPortada.setTag(position); 
    holder.txtNombre.setText(cursor.getString(cursor.getColumnIndex(Constantes.ALB_NOMBRE))); 
    holder.txtArtista.setText(cursor.getString(cursor.getColumnIndex(Constantes.ALB_ARTISTA))); 
    ObtenerPortada oP = new ObtenerPortada(cursor.getInt(cursor.getColumnIndex(Constantes.ALB_ID)), holder.imgVwPortada); 
    oP.execute(Datos.getActividadActual()); 
} 

這是我ViewHolder

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 

    private Activity actividad; 
    public TextView txtNombre; 
    public TextView txtArtista; 
    public ImageView imgVwPortada; 
    public RelativeLayout container; 

    public ViewHolder(View v, Activity actividad) { 
     super(v); 
     this.actividad = actividad; 
     container = (RelativeLayout) itemView.findViewById(R.id.artista); 
     txtNombre = (TextView)v.findViewById(R.id.txtNombre); 
     txtArtista = (TextView)v.findViewById(R.id.txtArtista); 
     imgVwPortada = (ImageView)v.findViewById(R.id.imgVwPortada); 
     v.setOnClickListener(this); 
    } 
} 

,這是我的AsyncTask類

private class ObtenerPortada extends AsyncTask<Activity, Void, Bitmap> { 

    long ID; 
    private ImageView imv; 
    private String path; 

    public ObtenerPortada(long ID, ImageView imv) { 
     this.ID = ID; 
     this.imv = imv; 
     this.path = imv.getTag().toString(); 
    } 

    @Override 
    protected Bitmap doInBackground(Activity... params) { 
     WeakReference<Bitmap> bitmap = null; 
     try { 
      Uri trackUri = ContentUris.withAppendedId(Constantes.uriAlbumesArt, ID); 
      Bitmap bit = MediaStore.Images.Media.getBitmap(params[0].getContentResolver(), trackUri); 
      bitmap = new WeakReference<>(ReducirImagenes.reducirBitmap(200, 200, bit)); 
     } catch (Exception e) { 
      bitmap = new WeakReference<>(Datos.getPortadaDefault()); 
      return null; 
     } 
     return bitmap.get(); 
    } 

    @Override 
    protected void onPostExecute(Bitmap result) { 
     super.onPostExecute(result); 
     if (!imv.getTag().toString().equals(path)) { 
      return; 
     } 
     if(result != null && imv != null){ 
      imv.setImageBitmap(result); 
      imv.setAlpha(0f); 
      imv.setVisibility(View.VISIBLE); 
      imv.animate().alpha(1f).setDuration(200).setListener(null); 
     } 
    } 
} 

這是一個例子,我的問題:https://www.youtube.com/watch?v=x_1yXh6J2Ks

回答

0

默認情況下AsyncTask在單個後臺線程上串行執行。您可以使用executeOnExecutor()替代並提供您自己的Executor實例(例如ThreadPoolExecutor)來覆蓋此行爲。

此外,它可能有助於跟蹤ViewHolder中的任務,以便在回收時可以取消之前的任務,如果該任務尚未開始。

+0

+1用於檢查圖像加載仍然是必要的。您可以在onPostExecute中重新使用現有的檢查,然後在doInBackground中執行該檢查,以避免加載不再可見的事物。 – Buddy

0

Android對默認情況下默認運行多少個AsyncTasks也有限制AsyncTasks以線性方式運行。通過執行onExecutor繞過LinearExucutions,同時爲了避免限制,您必須創建自己的線程池。

BlockingQueue<Runnable> workQueue; 
Executor threadPoolExecutor; 

workQueue = new LinkedBlockingQueue<Runnable>(maximumPoolSize); 
threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue); 

現在與執行

new AsyncTaskTest().executeOnExecutor(threadPoolExecutor,null, null, null); 

這裏執行的AsyncTask是PhotoManager一個例子,你也可以使用存儲JavaHeap以外的圖像一些先進的圖像加載庫 - Fresco Library從Facebook。壁畫也處理不加載不可見的圖像。