The following describes how to expand the disk cache of the UniversialImageLoader image download framework for Android (2 ),
Compared with the first article, this article describes the continuation of the disk cache. Here we mainly focus on four classes: DiskLruCache, LruDiskCache, StrictLineReader, and Util.
Next we will analyze them one by one. Not much nonsense.
First, let's take a look at DiskLruCache.
What are the main functions of this class? Let's take a look at the comments of a class:
/** * A cache that uses a bounded amount of space on a filesystem. Each cache * entry has a string key and a fixed number of values. Each key must match * the regex <strong>[a-z0-9_-]{1,64}</strong>. Values are byte sequences, * accessible as streams or files. Each value must be between {@code 0} and * {@code Integer.MAX_VALUE} bytes in length. * <p>This class is tolerant of some I/O errors. If files are missing from the * filesystem, the corresponding entries will be dropped from the cache. If * an error occurs while writing a cache value, the edit will fail silently. * Callers should handle other problems by catching {@code IOException} and * responding appropriately. */
Do not worry about children's shoes that are not interested in English:
This is a limited space-based Cache built based on the file system. Each cache entry has a sequence of string keys and fixed numbers. Each key must match the regular expression <strong> [a-z0-9 _-] {} </strong>. A value is a byte sequence that can be accessed as a stream or file. Each value must be between 0 and the largest integer in length. This cache class is tolerant of some I/O operation rooms. If some files are lost from the file system, the corresponding cache entry token will be removed from the cache. If an error occurs while writing a cached value,
The current editing will also be silently abolished, and the callback will handle some other problems by capturing some I/O exceptions and verifying responses.
Due to the large amount of DiskLruCache code, we will introduce it from some core variables and methods. The core variables are as follows:
static final String JOURNAL_FILE = "journal";static final String JOURNAL_FILE_TEMP = "journal.tmp";static final String JOURNAL_FILE_BACKUP = "journal.bkp";static final String MAGIC = "libcore.io.DiskLruCache";static final String VERSION_1 = "1";static final long ANY_SEQUENCE_NUMBER = -1;static final Pattern LEGAL_KEY_PATTERN = Pattern.compile("[a-z0-9_-]{1,64}");private static final String CLEAN = "CLEAN";private static final String DIRTY = "DIRTY";private static final String REMOVE = "REMOVE";private static final String READ = "READ";private final File directory;private final File journalFile;private final File journalFileTmp;private final File journalFileBackup;private final int appVersion;private long maxSize;private int maxFileCount;private final int valueCount;private long size = 0;private int fileCount = 0;private Writer journalWriter;private final LinkedHashMap<String, Entry> lruEntries =new LinkedHashMap<String, Entry>(0, 0.75f, true);private int redundantOpCount;private long nextSequenceNumber = 0;final ThreadPoolExecutor executorService =new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
The variables above are roughly classified, including: the name of the log file and the definition of the variables in the first five lines of the log file, the file size and quantity restrictions, as well as a javashashmap to maintain a cache queue, finally there is a thread pool.
Next we will give a general introduction to the functions of the functions:
1. readJournal: 1. Calculate the number of cached logs, 2. Calculate the number of redundant lines in the cached log files. 3. Read and process cached logs. data of each row in
2. The readJournalLine function is used to perform operations on each log row. When a keyword is encountered in the log, check whether the object mapped by the current keyword exists from the cached degree column. If it does not exist, create a new object with the current keyword and put it in the current cache queue.
3. processJournal calculates the initial size and recycles some garbage in the cache. Dirty entries will be considered as conflicting and recycled.
4. The rebuildJournal function is used to create a new log file that deletes a large amount of redundant information. If the current log file exists, the current log file will be replaced.
5,
public synchronized Snapshot get(String key) throws IOException
This function returns a snapshot of the file entry named key. If the current value is returned, it will be moved to the header of the LRU queue.
6,
public synchronized boolean remove(String key) throws IOException
If the current object exists and can be deleted, delete the object of the current object. The object being edited cannot be deleted.
Next, let's take a look at the three important internal classes in this class: Snapshot, Editor, and Entry.
This section describes the functions of these three classes.
Snapshot is a Snapshot of the cached object values. Editor is the value of the cached object. An Entry is the data model of the cached object.
Next, let's take a look at the main functions of the LruDiskCache class.
Like the name of this class, this is a disk cache that has not been used for the most recent time. The general functions of this class are clear.
We will see such a member variable in this class.
protected DiskLruCache cache;
It can be seen that the current class is an adapter of the DiskLruCache interface for disk cache. Believe it? We can see from the following method:
1,
@Overridepublic File getDirectory() {return cache.getDirectory();}
Obtain the current cache directory.
2,
public File get(String imageUri) {DiskLruCache.Snapshot snapshot = null;try {snapshot = cache.get(getKey(imageUri));return snapshot == null ? null : snapshot.getFile(0);} catch (IOException e) {L.e(e);return null;} finally {if (snapshot != null) {snapshot.close();}}}
Obtain the image file handle using the image uri object. It is implemented through snapshots in DiskLruCache.
3,
public boolean save(String imageUri, InputStream imageStream, IoUtils.CopyListener listener) throws IOException {DiskLruCache.Editor editor = cache.edit(getKey(imageUri));if (editor == null) {return false;}OutputStream os = new BufferedOutputStream(editor.newOutputStream(0), bufferSize);boolean copied = false;try {copied = IoUtils.copyStream(imageStream, os, listener, bufferSize);} finally {IoUtils.closeSilently(os);if (copied) {editor.commit();} else {editor.abort();}}return copied;}
The file editing class Editor in DiskLruCache is used to write the current file input stream to the generated file.
And so on.
Next we will talk about the class StrictLineReader. We can also understand it as a help class, which is specially designed to read the content of cached logs.
Observe the following method:
public String readLine() throws IOException {synchronized (in) {if (buf == null) {throw new IOException("LineReader is closed");}if (pos >= end) {fillBuf();}for (int i = pos; i != end; ++i) {if (buf[i] == LF) {int lineEnd = (i != pos && buf[i - 1] == CR) ? i - 1 : i;String res = new String(buf, pos, lineEnd - pos, charset.name());pos = i + 1;return res;}}ByteArrayOutputStream out = new ByteArrayOutputStream(end - pos + 80) {@Overridepublic String toString() {int length = (count > 0 && buf[count - 1] == CR) ? count - 1 : count;try {return new String(buf, 0, length, charset.name());} catch (UnsupportedEncodingException e) {throw new AssertionError(e); // Since we control the charset this will never happen.}}};while (true) {out.write(buf, pos, end - pos);// Mark unterminated line in case fillBuf throws EOFException or IOException.end = -1;fillBuf();for (int i = pos; i != end; ++i) {if (buf[i] == LF) {if (i != pos) {out.write(buf, pos, i - pos);}pos = i + 1;return out.toString();}}}}}
In the last Util class, three methods are encapsulated,
1. readFully reads content from Reader and concatenates it into a complete string
2. econtents iteratively deletes the contents of the directory of the file
3. closeQuietly silently closes the file stream
OK. Here we will talk about the expansion of disk storage. I hope it will be helpful to you.