How check if a DiskLruCache already exists? (Android)

限于喜欢 提交于 2019-12-29 09:35:11

问题


I´m using that way of cache Bitmaps in my app Using DiskLruCache in android 4.0 does not provide for openCache method

Thing is that I´m using that line in onCreate()

DiskLruImageCache dlic=new DiskLruImageCache(getApplicationContext(),"bckgCache", CACHESIZE, CompressFormat.PNG, 70);

and I´m pretty sure that It is overwriting my DiskLruCache everytime the app is opened "as new", so I´m not being able to recover some Bitmaps I catch las time user opened the app. So here is the question

How can I check I there´s already a DislLruCache created for an specific App so I will only create It If It doesn´t exist?

That's the class I'm using from the above URL

 public class DiskLruImageCache {

private DiskLruCache mDiskCache;
private CompressFormat mCompressFormat = CompressFormat.PNG;
private int mCompressQuality = 70;
private static final int APP_VERSION = 1;
private static final int VALUE_COUNT = 1;
private static final String TAG = "DiskLruImageCache";

public DiskLruImageCache( Context context,String uniqueName, int diskCacheSize,
    CompressFormat compressFormat, int quality ) {
    try {
            final File diskCacheDir = getDiskCacheDir(context, uniqueName );
            mDiskCache = DiskLruCache.open( diskCacheDir, APP_VERSION, VALUE_COUNT, diskCacheSize );
            mCompressFormat = compressFormat;
            mCompressQuality = quality;
        } catch (IOException e) {
            e.printStackTrace();
        }
}

private boolean writeBitmapToFile( Bitmap bitmap, DiskLruCache.Editor editor )
    throws IOException, FileNotFoundException {
    BufferedOutputStream out = null;
    try {
        out = new BufferedOutputStream( editor.newOutputStream( 0 ), Utils.IO_BUFFER_SIZE );
        return bitmap.compress( mCompressFormat, mCompressQuality, out );
    } finally {
        if ( out != null ) {
            out.close();
        }
    }
}

private File getDiskCacheDir(Context context, String uniqueName) {

// Check if media is mounted or storage is built-in, if so, try and use external cache dir
// otherwise use internal cache dir
    final String cachePath =
        Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ||
                !Utils.isExternalStorageRemovable() ?
                Utils.getExternalCacheDir(context).getPath() :
                context.getCacheDir().getPath();

    return new File(cachePath + File.separator + uniqueName);
}

public void put( String key, Bitmap data ) {

    DiskLruCache.Editor editor = null;
    try {
        editor = mDiskCache.edit( key );
        if ( editor == null ) {
            return;
        }

        if( writeBitmapToFile( data, editor ) ) {               
            mDiskCache.flush();
            editor.commit();
            if ( BuildConfig.DEBUG ) {
               Log.d( "cache_test_DISK_", "image put on disk cache " + key );
            }
        } else {
            editor.abort();
            if ( BuildConfig.DEBUG ) {
                Log.d( "cache_test_DISK_", "ERROR on: image put on disk cache " + key );
            }
        }   
    } catch (IOException e) {
        if ( BuildConfig.DEBUG ) {
            Log.d( "cache_test_DISK_", "ERROR on: image put on disk cache " + key );
        }
        try {
            if ( editor != null ) {
                editor.abort();
            }
        } catch (IOException ignored) {
        }           
    }

}

public Bitmap getBitmap( String key ) {

    Bitmap bitmap = null;
    DiskLruCache.Snapshot snapshot = null;
    try {

        snapshot = mDiskCache.get( key );
        if ( snapshot == null ) {
            return null;
        }
        final InputStream in = snapshot.getInputStream( 0 );
        if ( in != null ) {
            final BufferedInputStream buffIn = 
            new BufferedInputStream( in, Utils.IO_BUFFER_SIZE );
            bitmap = BitmapFactory.decodeStream( buffIn );              
        }   
    } catch ( IOException e ) {
        e.printStackTrace();
    } finally {
        if ( snapshot != null ) {
            snapshot.close();
        }
    }

    if ( BuildConfig.DEBUG ) {
        Log.d( "cache_test_DISK_", bitmap == null ? "" : "image read from disk " + key);
    }

    return bitmap;

}

public boolean containsKey( String key ) {

    boolean contained = false;
    DiskLruCache.Snapshot snapshot = null;
    try {
        snapshot = mDiskCache.get( key );
        contained = snapshot != null;
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if ( snapshot != null ) {
            snapshot.close();
        }
    }

    return contained;

}

public void clearCache() {
    if ( BuildConfig.DEBUG ) {
        Log.d( "cache_test_DISK_", "disk cache CLEARED");
    }
    try {
        mDiskCache.delete();
    } catch ( IOException e ) {
        e.printStackTrace();
    }
}

public File getCacheFolder() {
    return mDiskCache.getDirectory();
}

And this is what I'm doing into my Activity, wich doesn't works. If you try offline works the first time, second It doesn't (null pointer in OnPause because It can't find any Bitmap in the folder). If you try Online always works, but, if you try online, and then offline, instead load the previous downloaded image, is stops (null pointer), so, main problem is that It, for whatever reason, doesn't records or reads anything in the cache folder

 public class Portada extends Activity {
private LinearLayout linearLayout;
private BitmapDrawable drawableBitmap;
private Bitmap b;
private DiskLruImageCache dlic;
private final String urlFondo="http://adapp.hostei.com/img/portada.jpg";
private final int MAXMEMORY = (int) (Runtime.getRuntime().maxMemory() / 1024);
private final int CACHESIZE = MAXMEMORY / 8;
private final String KEYPORTADA="bckportada";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_portada);
    linearLayout=(LinearLayout)findViewById(R.id.fondoPortada);

    Log.i("OnCreate","Starting");

     File cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"bckgCache");

     if(!cacheDir.exists()){ // check if it exits. if not create one
         Log.i("OnCreate","Create not exsisting folder");
         cacheDir.mkdirs(); 
         dlic=new DiskLruImageCache(Portada.this,cacheDir.getName(), CACHESIZE, CompressFormat.PNG, 70);
     }
     else{
         dlic=new DiskLruImageCache(Portada.this,cacheDir.getName(), CACHESIZE, CompressFormat.PNG, 70);
     } 
}   



@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    Log.i("OnResume","Starting");

    //checks if there's already a background image on cache
    boolean hayportada=comprobarSiHayPortadaEnCache();

    //creates a bckImage from R.drawable image if there's any already in cache
    //this should only occurs once, the very first time the App runs
    if(!hayportada){
        b=BitmapFactory.decodeResource(getResources(), R.drawable.portada);
        dlic.put(KEYPORTADA, b);
        Log.i("onResume","Creates bckgImage from R.drawable");
    }


    //checks if there's any connection and if yes, loads the url image into cache and puts It as background
    //if not load the image of the previous if
    if(CheckOnline.isOnline(Portada.this)){
        cargarPortadaUrl(urlFondo);//loads image from url and stores in cache
        cargarImagenPortada(b);//put image as layout background
        Log.i("onResume","there is online, down img");
    }
    else{
        b=dlic.getBitmap(KEYPORTADA);
        cargarImagenPortada(b);
        Log.i("onResume","there's not online ");
    }
}

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    dlic.put(KEYPORTADA, b);//just in case, It's already done in OnResume;
    Log.i("onPause","stores Bitmap");
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_portada, menu);
    return true;
}

/**
 * Takes an image from url and stores It in cache
 * 
 */
public void cargarPortadaUrl(String urlFondo){
    DownloadImageTask dit=new DownloadImageTask();//Async task that downloads an img
    try {
        b=dit.execute(urlFondo).get();
        dlic.put(KEYPORTADA, b);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ExecutionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}


//loads a Bitmap as Layout Background image
public void cargarImagenPortada(Bitmap bitm){
    drawableBitmap=new BitmapDrawable(bitm);
    linearLayout.setBackgroundDrawable(drawableBitmap); 
}

//checks if there's any 
public boolean comprobarSiHayPortadaEnCache(){
    b=dlic.getBitmap(KEYPORTADA);
    if(b==null)return false;
    else return true;
}

}


回答1:


Check if sd card is mounted. Get the path of the sdcard. Check if the folder under sdcard already exists, if not create one.

Remember to add permission in manifest file

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
if(android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
{
  File cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"MyFolder");

    if(!cacheDir.exists())
        cacheDir.mkdirs();
}

You can use the below. Found this on developer site in the below link

File cacheDir = getDiskCacheDir(ActivityName.this, "thumbnails");  
if(!cacheDir.exists()) // check if it exits. if not create one
 {
    cacheDir.mkdirs(); 
 } 

public static File getDiskCacheDir(Context context, String uniqueName) {
// Check if media is mounted or storage is built-in, if so, try and use external cache dir
// otherwise use internal cache dir
final String cachePath =
        Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ||
                !isExternalStorageRemovable() ? getExternalCacheDir(context).getPath() :
                        context.getCacheDir().getPath();

return new File(cachePath + File.separator + uniqueName);
}

For more information check the link below

http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

I see you have used getAppliactionContext(). Check the link below

When to call activity context OR application context?. Get to know when to use activity context and getApplicationContext()

Edit:

   File cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"MyFolder");
 if(!cacheDir.exists()) // check if it exits. if not create one
  {
   cacheDir.mkdirs(); 
   DiskLruImageCache dlic=new DiskLruImageCache(ActivityName.this,cacheDir, CACHESIZE, CompressFormat.PNG, 70);
  }
  else
   {
      DiskLruImageCache dlic=new DiskLruImageCache(ActivityName.this,cacheDir, CACHESIZE, CompressFormat.PNG, 70);
   } 

Edit: 2

As you can see below you are just passing the file not creating a new one.

private DiskLruCache(File directory, int appVersion, int valueCount, long maxSize) {
    this.directory = directory;
    this.appVersion = appVersion;
    this.journalFile = new File(directory, JOURNAL_FILE);
    this.journalFileTmp = new File(directory, JOURNAL_FILE_TMP);
    this.valueCount = valueCount;
    this.maxSize = maxSize;
}

public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
        throws IOException {
    if (maxSize <= 0) {
        throw new IllegalArgumentException("maxSize <= 0");
    }
    if (valueCount <= 0) {
        throw new IllegalArgumentException("valueCount <= 0");
    }

    // prefer to pick up where we left off
    DiskLruCache cache = new DiskLruCache(directory, appVersion, valueCount, maxSize);
    if (cache.journalFile.exists()) {
        try {
            cache.readJournal();
            cache.processJournal();
            cache.journalWriter = new BufferedWriter(new FileWriter(cache.journalFile, true),
                    IO_BUFFER_SIZE);
            return cache;
        } catch (IOException journalIsCorrupt) {
             System.logW("DiskLruCache " + directory + " is corrupt: "
                    + journalIsCorrupt.getMessage() + ", removing");
            cache.delete();
        }
    }

    // create a new empty cache
    directory.mkdirs();
    cache = new DiskLruCache(directory, appVersion, valueCount, maxSize);
    cache.rebuildJournal();
    return cache;
}


来源:https://stackoverflow.com/questions/16054007/how-check-if-a-disklrucache-already-exists-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!