2012-12-21 6 views
17

Sto usando UIL per caricare le immagini in un listview.Come forzare una cancellazione della cache usando Universal Image Loader Android?

Quando premo a lungo un'immagine nella lista, mostro una finestra di dialogo per modificare quella foto, sostituendola con una nuova usando la fotocamera.

Se faccio una nuova foto, quando la finestra di dialogo viene chiusa la mia listview mostra ancora la vecchia immagine (poiché è memorizzata nella cache). Se chiudo e riavvia la mia applicazione quando vado al mio listview, la nuova immagine è correttamente lì.

Ecco come ho creato UIL:

// Get singletone instance of ImageLoader 
    imageLoader = ImageLoader.getInstance(); 

    //set display options for image loader 
    DisplayImageOptions displayOptions = new DisplayImageOptions.Builder() 
    .cacheInMemory() 
    .displayer(new FadeInBitmapDisplayer(500)) //fade in images 
    .resetViewBeforeLoading() 
    .build(); 

    //set image loader options 
    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this).defaultDisplayImageOptions(displayOptions).build(); 

    // Initialize ImageLoader with configuration. 
    imageLoader.init(config); 

Se rimuovo .cacheInMemory() tutto funziona però. Mi sto solo chiedendo se posso cancellare la cache solo aprendo la mia finestra di dialogo. Ho provato ad accedere a ImageView selezionato e chiamare myImageView.invalidate() quando si apre la finestra di dialogo senza successo.

Le immagini vengono caricate da file:

// Load and display image asynchronously 
imageLoader.displayImage(file_prefix + image_path, image); 

Qualche suggerimento?

Edit: codice per creare un menu contestuale quando si preme a lungo un'immagine, ho cercato di cancellare la cache c'è:

@Override 
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 
    super.onCreateContextMenu(menu, v, menuInfo); 

    //get info about item selected 
    AdapterView.AdapterContextMenuInfo info; 
    try { 
     // Casts the incoming data object into the type for AdapterView objects. 
     info = (AdapterView.AdapterContextMenuInfo) menuInfo; 
    } catch (ClassCastException e) { 
     // If the menu object can't be cast, logs an error. 
     Log.e("no info", "bad menuInfo", e); 
     return; 
    } 
    Cursor cursor = (Cursor) getListAdapter().getItem(info.position); 
    if (cursor == null) { 
     // For some reason the requested item isn't available, do nothing 
     return; 
    } 

    //remove selected image from cache (if it is an image) 
    imageUrl = cursor.getString(cursor.getColumnIndex("image_path")); 
    if (!imageUrl.equalsIgnoreCase("")) { 
     MemoryCacheUtil.removeFromCache(imageUrl, imageLoader.getMemoryCache()); 
    } 

    Log.i("imageUrl", imageUrl); 

    //get defect row ID and text content to pass it to defect activity 
    defect_row_id = cursor.getLong(cursor.getColumnIndex("_id")); 
    defect_txt = cursor.getString(cursor.getColumnIndex("defect")); 

    MenuInflater inflater = getMenuInflater(); 

    Log.i("cursor", DatabaseUtils.dumpCursorToString(cursor)); 

    //set project identifier in context menu header, mapping cursor sequence of values 
    menu.setHeaderTitle(getString(R.string.select_an_option)); 
    inflater.inflate(R.menu.menu_defect_row, menu); 

} 

Quando una voce di menu (modificare o eliminare) è selezionato

@Override 
public boolean onContextItemSelected(MenuItem item) { 
    //AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); 
    switch (item.getItemId()) { 

    case R.id.edit: 

     //open defect activity with the specified image and defect pre-loaded 
     Intent editDefectIntent = new Intent(this, DefectActivity.class); 

     editDefectIntent.putExtra("defect_row_id", defect_row_id); 
     editDefectIntent.putExtra("imageUrl", imageUrl); 

     startActivity(editDefectIntent); 

     return true; 
    case R.id.delete: 

     askDeleteConfirm(); 

     return true; 

    default: 
     return false; 
    } 

}//onContextItemSelected 

Edit: il codice per visualizzare l'elenco delle immagini

@Override 
public void onResume() { 
    super.onResume(); 

    //open connection to db 
    db = new DBAdapter(this); 
    db.open(); 

    Log.i("DefectListActivity -> onResume", "called"); 

    // get all defects for this unit 
    defectList = db.getAllDefectsByUnit(unit_id); 
    // create an array adapter and let it to display our row 
    defects = new SimpleCursorAdapter(this, R.layout.defect_row, defectList, new String[] { "defect", "image_path" }, new int[] { R.id.defect, R.id.image }, 0); 

    //set custom view using ViewBinder 
    SimpleCursorAdapter.ViewBinder binder = new SimpleCursorAdapter.ViewBinder() { 
     @Override 
     public boolean setViewValue(View view, Cursor cursor, int columnIndex) { 

      int placeholder_id = getResources().getIdentifier("placeholder", "drawable", getPackageName()); 

      //get column name 
      String name = cursor.getColumnName(columnIndex); 

      //for the thumbnail column,if we have an image replace the placeholder 
      if ("image_path".equals(name)) { 

       ImageView image = (ImageView) view.findViewById(R.id.image); 
       //Bitmap thumbnail; 
       String image_path = cursor.getString(columnIndex); 

       Log.i("image_path ->", image_path); 

       if (!image_path.equalsIgnoreCase("")) { 

       // Load and display image asynchronously 
       imageLoader.displayImage(file_prefix + image_path, image); 

       } else { 

        image.setImageResource(placeholder_id); 


        } 

       return true; 

      } 

      //for the defect column, just add the text to the view 
      if ("defect".equals(name)) { 

       String defect_text = cursor.getString(columnIndex); 

       TextView defect_holder = (TextView) view.findViewById(R.id.defect); 
       defect_holder.setText(defect_text); 

       return true; 
      } 

      return false; 
     } 
    }; 

    defects.setViewBinder(binder); 

    setListAdapter(defects); 

}//onResume 

risposta

10

penso che si dovrebbe eliminare l'immagine cache in memoria cache quando si apre la finestra di dialogo. Utilizzare MemoryCacheUtil per questo:

MemoryCacheUtils.removeFromCache(imageUrl, imageLoader.getMemoryCache()); 
+0

Ho provato, non funziona. Sto aprendo un menu di scelta rapida, quindi una finestra di dialogo. Ho aggiunto queste righe al mio 'onCreateContextMenu' ma non fa nulla. Ho anche provato a passare l'URL dell'immagine alla finestra di dialogo e svuotare la cache da lì ottenendo l'imageLoader singleton, sempre lo stesso. – Mirko

+0

Chiamate '' 'imageLoader.displayImage (file_prefix + image_path, image);' '' dopo aver sostituito l'immagine con una nuova usando la fotocamera? – NOSTRA

+0

effettivamente PRIMA, quando si apre la finestra di dialogo – Mirko

20

Questo dovrebbe funzionare:

imageLoader.clearMemoryCache(); 
+7

Per cancellare la cache di memoria: 'imageLoader.clearMemoryCache();' e per cancellare la cache del disco: 'imageLoader.clearDiscCache();' – hannanessay

27

Se si caching che sia in memoria e disco, ad esempio:

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())   
     .memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024)) 
     .discCache(new UnlimitedDiscCache(cacheDir)) 
......... 

Assicurarsi di rimuoverla da entrambi di essi, quindi ricaricare la vista dell'immagine.

MemoryCacheUtils.removeFromCache(url, ImageLoader.getInstance().getMemoryCache()); 
DiscCacheUtils.removeFromCache(url, ImageLoader.getInstance().getDiscCache()); 
+4

Mi hai appena salvato la vita. – idish

+2

Non ho trovato 'DiscCacheUtils' né' getDiscCache'. Penso che volessi dire 'DiskCacheUtils'' getDiskCache' – Antonio

+1

Ero nella versione precedente della libreria, sto usando 'ImageLoader.getInstance(). GetDiscCache() ImageLoader.getInstance(). GetMemoryCache() ' E' DiscCacheUtil' è ancora lì per la versione 1.9. + Credo. – Bundeeteddee