0

我在我的应用程序中使用这种缓存位图的方式在 android 4.0 中使用 DiskLruCache 不提供 openCache 方法

事情是我在 onCreate() 中使用了那条线

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

而且我很确定每次打开应用程序“如新”时它都会覆盖我的 DiskLruCache,因此我无法恢复上次用户打开应用程序时捕获的一些位图。所以这是问题

如何检查我已经为特定应用程序创建了 DislLruCache,所以我只会在它不存在时创建它?

这就是我在上面的 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();
}

这就是我在我的活动中所做的,这是行不通的。如果您第一次尝试脱机工作,第二次它不会(OnPause 中的空指针,因为它在文件夹中找不到任何位图)。如果您尝试在线总是有效,但是,如果您尝试在线,然后离线,而不是加载以前下载的图像,则会停止(空指针),所以,主要问题是它,无论出于何种原因,都不会记录或读取缓存文件夹中的任何内容

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

}

4

1 回答 1

2

检查是否安装了sd卡。获取 sdcard 的路径。检查sdcard下的文件夹是否已经存在,如果没有就创建一个。

记得在清单文件中添加权限

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

您可以使用以下内容。在以下链接的开发者网站上找到了这个

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

有关更多信息,请查看以下链接

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

我看你用过getAppliactionContext()。检查下面的链接

何时调用活动上下文或应用程序上下文?. 了解何时使用活动上下文和 getApplicationContext()

编辑:

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

编辑:2

正如您在下面看到的,您只是传递文件而不是创建新文件。

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;
}
于 2013-04-17T07:28:37.813 回答