Android4,系统学Android从零开始

Android4,系统学Android从零开始private final LinkedHashMa string entry lruEntries new LinkedHashMa string entry 0 0 75f true private int redundantOpC To differentiat between old and string string

大家好,我是讯享网,很高兴认识大家。
  1. private final LinkedHashMap<String, Entry> lruEntries
  2. = new LinkedHashMap<String, Entry>(0, 0.75f, true);
  3. private int redundantOpCount;
  1. /
  2. * To differentiate between old and current snapshots, each entry is given
  3. * a sequence number each time an edit is committed. A snapshot is stale if
  4. * its sequence number is not equal to its entry’s sequence number.
  5. */
  6. private long nextSequenceNumber = 0;
  1. / This cache uses a single background thread to evict entries. */
  2. private final ExecutorService executorService = new ThreadPoolExecutor(0, 1,
  3. 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
  4. private final Callable<Void> cleanupCallable = new Callable<Void>() {
  5. @Override public Void call() throws Exception {
  6. synchronized (DiskLruCache.this) {
  7. if (journalWriter == null) {
  8. return null; // closed
  9. }
  10. trimToSize();
  11. if (journalRebuildRequired()) {
  12. rebuildJournal();
  13. redundantOpCount = 0;
  14. }
  15. }
  16. return null;
  17. }
  18. };
  1. private DiskLruCache(File directory, int appVersion, int valueCount, long maxSize) {
  2. this.directory = directory;
  3. this.appVersion = appVersion;
  4. this.journalFile = new File(directory, JOURNAL_FILE);
  5. this.journalFileTmp = new File(directory, JOURNAL_FILE_TMP);
  6. this.valueCount = valueCount;
  7. this.maxSize = maxSize;
  8. }
  1. /
  2. * Opens the cache in {@code directory}, creating a cache if none exists
  3. * there.
  4. *
  5. * @param directory a writable directory
  6. * @param appVersion
  7. * @param valueCount the number of values per cache entry. Must be positive.
  8. * @param maxSize the maximum number of bytes this cache should use to store
  9. * @throws IOException if reading or writing the cache directory fails
  10. */
  11. public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
  12. throws IOException {
  13. if (maxSize <= 0) {
  14. throw new IllegalArgumentException(“maxSize <= 0”);
  15. }
  16. if (valueCount <= 0) {
  17. throw new IllegalArgumentException(“valueCount <= 0”);
  18. }
  1. // prefer to pick up where we left off
  2. DiskLruCache cache = new DiskLruCache(directory, appVersion, valueCount, maxSize);
  3. if (cache.journalFile.exists()) {
  4. try {
  5. cache.readJournal();
  6. cache.processJournal();
  7. cache.journalWriter = new BufferedWriter(new FileWriter(cache.journalFile, true));
  8. return cache;
  9. } catch (IOException journalIsCorrupt) {
  10. System.logW("DiskLruCache " + directory + " is corrupt: "
  11. + journalIsCorrupt.getMessage() + “, removing”);
  12. cache.delete();
  13. }
  14. }
  1. // create a new empty cache
  2. directory.mkdirs();
  3. cache = new DiskLruCache(directory, appVersion, valueCount, maxSize);
  4. cache.rebuildJournal();
  5. return cache;
  6. }
  1. private void readJournal() throws IOException {
  2. InputStream in = new BufferedInputStream(new FileInputStream(journalFile));
  3. try {
  4. String magic = Streams.readAsciiLine(in);
  5. String version = Streams.readAsciiLine(in);
  6. String appVersionString = Streams.readAsciiLine(in);
  7. String valueCountString = Streams.readAsciiLine(in);
  8. String blank = Streams.readAsciiLine(in);
  9. if (!MAGIC.equals(magic)
  10. || !VERSION_1.equals(version)
  11. || !Integer.toString(appVersion).equals(appVersionString)
  12. || !Integer.toString(valueCount).equals(valueCountString)
  13. || !“”.equals(blank)) {
  14. throw new IOException(“unexpected journal header: [”
  15. + magic + ", " + version + ", " + valueCountString + ", " + blank + “]”);
  16. }
  1. while (true) {
  2. try {
  3. readJournalLine(Streams.readAsciiLine(in));
  4. } catch (EOFException endOfJournal) {
  5. break;
  6. }
  7. }
  8. } finally {
  9. IoUtils.closeQuietly(in);
  10. }
  11. }
  1. private void readJournalLine(String line) throws IOException {
  2. String[] parts = line.split(" ");
  3. if (parts.length < 2) {
  4. throw new IOException("unexpected journal line: " + line);
  5. }
  1. String key = parts[1];
  2. if (parts[0].equals(REMOVE) && parts.length == 2) {
  3. lruEntries.remove(key);
  4. return;
  5. }
  1. Entry entry = lruEntries.get(key);
  2. if (entry == null) {
  3. entry = new Entry(key);
  4. lruEntries.put(key, entry);
  5. }
  1. if (parts[0].equals(CLEAN) && parts.length == 2 + valueCount) {
  2. entry.readable = true;
  3. entry.currentEditor = null;
  4. entry.setLengths(Arrays.copyOfRange(parts, 2, parts.length));
  5. } else if (parts[0].equals(DIRTY) && parts.length == 2) {
  6. entry.currentEditor = new Editor(entry);
  7. } else if (parts[0].equals(READ) && parts.length == 2) {
  8. // this work was already done by calling lruEntries.get()
  9. } else {
  10. throw new IOException("unexpected journal line: " + line);
  11. }
  12. }
  1. /
  2. * Computes the initial size and collects garbage as a part of opening the
  3. * cache. Dirty entries are assumed to be inconsistent and will be deleted.
  4. */
  5. private void processJournal() throws IOException {
  6. deleteIfExists(journalFileTmp);
  7. for (Iterator<Entry> i = lruEntries.values().iterator(); i.hasNext(); ) {
  8. Entry entry = i.next();
  9. if (entry.currentEditor == null) {
  10. for (int t = 0; t < valueCount; t++) {
  11. size += entry.lengths[t];
  12. }
  13. } else {
  14. entry.currentEditor = null;
  15. for (int t = 0; t < valueCount; t++) {
  16. deleteIfExists(entry.getCleanFile(t));
  17. deleteIfExists(entry.getDirtyFile(t));
  18. }
  19. i.remove();
  20. }
  21. }
  22. }
  1. /
  2. * Creates a new journal that omits redundant information. This replaces the
  3. * current journal if it exists.
  4. */
  5. private synchronized void rebuildJournal() throws IOException {
  6. if (journalWriter != null) {
  7. journalWriter.close();
  8. }
  1. Writer writer = new BufferedWriter(new FileWriter(journalFileTmp));
  2. writer.write(MAGIC);
  3. writer.write(“\n”);
  4. writer.write(VERSION_1);
  5. writer.write(“\n”);
  6. writer.write(Integer.toString(appVersion));
  7. writer.write(“\n”);
  8. writer.write(Integer.toString(valueCount));
  9. writer.write(“\n”);
  10. writer.write(“\n”);
  1. for (Entry entry : lruEntries.values()) {
  2. if (entry.currentEditor != null) {
  3. writer.write(DIRTY + ’ ’ + entry.key + ‘\n’);
  4. } else {
  5. writer.write(CLEAN + ’ ’ + entry.key + entry.getLengths() + ‘\n’);
  6. }
  7. }
  1. writer.close();
  2. journalFileTmp.renameTo(journalFile);
  3. journalWriter = new BufferedWriter(new FileWriter(journalFile, true));
  4. }
  1. private static void deleteIfExists(File file) throws IOException {
  2. try {
  3. Libcore.os.remove(file.getPath());
  4. } catch (ErrnoException errnoException) {
  5. if (errnoException.errno != OsConstants.ENOENT) {
  6. throw errnoException.rethrowAsIOException();
  7. }
  8. }
  9. }
  1. /
  2. * Returns a snapshot of the entry named {@code key}, or null if it doesn’t
  3. * exist is not currently readable. If a value is returned, it is moved to
  4. * the head of the LRU queue.
  5. */
  6. public synchronized Snapshot get(String key) throws IOException {
  7. checkNotClosed();
  8. validateKey(key);
  9. Entry entry = lruEntries.get(key);
  10. if (entry == null) {
  11. return null;
  12. }
  1. if (!entry.readable) {
  2. return null;
  3. }
  1. /*
  2. * Open all streams eagerly to guarantee that we see a single published
  3. * snapshot. If we opened streams lazily then the streams could come
  4. * from different edits.


    讯享网

  5. */
  6. InputStream[] ins = new InputStream[valueCount];
  7. try {
  8. for (int i = 0; i < valueCount; i++) {
  9. ins[i] = new FileInputStream(entry.getCleanFile(i));
  10. }
  11. } catch (FileNotFoundException e) {
  12. // a file must have been deleted manually!
  13. return null;
  14. }
  1. redundantOpCount++;
  2. journalWriter.append(READ + ’ ’ + key + ‘\n’);
  3. if (journalRebuildRequired()) {
  4. executorService.submit(cleanupCallable);
  5. }
  1. return new Snapshot(key, entry.sequenceNumber, ins);
  2. }
  1. /
  2. * Returns an editor for the entry named {@code key}, or null if another
  3. * edit is in progress.
  4. */
  5. public Editor edit(String key) throws IOException {
  6. return edit(key, ANY_SEQUENCE_NUMBER);
  7. }
  1. private synchronized Editor edit(String key, long expectedSequenceNumber) throws IOException {
  2. checkNotClosed();
  3. validateKey(key);
  4. Entry entry = lruEntries.get(key);
  5. if (expectedSequenceNumber != ANY_SEQUENCE_NUMBER
  6. && (entry == null || entry.sequenceNumber != expectedSequenceNumber)) {
  7. return null; // snapshot is stale
  8. }
  9. if (entry == null) {
  10. entry = new Entry(key);
  11. lruEntries.put(key, entry);
  12. } else if (entry.currentEditor != null) {
  13. return null; // another edit is in progress
  14. }
  1. Editor editor = new Editor(entry);
  2. entry.currentEditor = editor;
  1. // flush the journal before creating files to prevent file leaks
  2. journalWriter.write(DIRTY + ’ ’ + key + ‘\n’);
  3. journalWriter.flush();
  4. return editor;
  5. }
  1. /
  2. * Returns the directory where this cache stores its data.
  3. */
  4. public File getDirectory() {
  5. return directory;
  6. }
  1. /
  2. * Returns the maximum number of bytes that this cache should use to store
  3. * its data.
  4. */
  5. public long maxSize() {
  6. return maxSize;
  7. }
  1. /
  2. * Returns the number of bytes currently being used to store the values in
  3. * this cache. This may be greater than the max size if a background
  4. * deletion is pending.
  5. */
  6. public synchronized long size() {
  7. return size;
  8. }
  1. private synchronized void completeEdit(Editor editor, boolean success) throws IOException {
  2. Entry entry = editor.entry;
  3. if (entry.currentEditor != editor) {
  4. throw new IllegalStateException();
  5. }
  1. // if this edit is creating the entry for the first time, every index must have a value
  2. if (success && !entry.readable) {
  3. for (int i = 0; i < valueCount; i++) {
  4. if (!entry.getDirtyFile(i).exists()) {
  5. editor.abort();
  6. throw new IllegalStateException("edit didn’t create file " + i);
  7. }
  8. }
  9. }
  1. for (int i = 0; i < valueCount; i++) {
  2. File dirty = entry.getDirtyFile(i);
  3. if (success) {
  4. if (dirty.exists()) {
  5. File clean = entry.getCleanFile(i);
  6. dirty.renameTo(clean);
  7. long oldLength = entry.lengths[i];
  8. long newLength = clean.length();
  9. entry.lengths[i] = newLength;
  10. size = size - oldLength + newLength;
  11. }
  12. } else {
  13. deleteIfExists(dirty);
  14. }
  15. }
  1. redundantOpCount++;
  2. entry.currentEditor = null;
  3. if (entry.readable | success) {
  4. entry.readable = true;
  5. journalWriter.write(CLEAN + ’ ’ + entry.key + entry.getLengths() + ‘\n’);
  6. if (success) {
  7. entry.sequenceNumber = nextSequenceNumber++;
  8. }
  9. } else {
  10. lruEntries.remove(entry.key);
  11. journalWriter.write(REMOVE + ’ ’ + entry.key + ‘\n’);
  12. }
  1. if (size > maxSize || journalRebuildRequired()) {
  2. executorService.submit(cleanupCallable);
  3. }
  4. }
  1. /
  2. * We only rebuild the journal when it will halve the size of the journal
  3. * and eliminate at least 2000 ops.
  4. */
  5. private boolean journalRebuildRequired() {
  6. final int REDUNDANT_OP_COMPACT_THRESHOLD = 2000;
  7. return redundantOpCount >= REDUNDANT_OP_COMPACT_THRESHOLD
  8. && redundantOpCount >= lruEntries.size();
  9. }
  1. /
  2. * Drops the entry for {@code key} if it exists and can be removed. Entries
  3. * actively being edited cannot be removed.
  4. *
  5. * @return true if an entry was removed.
  6. */
  7. public synchronized boolean remove(String key) throws IOException {
  8. checkNotClosed();
  9. validateKey(key);
  10. Entry entry = lruEntries.get(key);
  11. if (entry == null || entry.currentEditor != null) {
  12. return false;
  13. }
  1. for (int i = 0; i < valueCount; i++) {
  2. File file = entry.getCleanFile(i);
  3. if (!file.delete()) {
  4. throw new IOException("failed to delete " + file);
  5. }
  6. size -= entry.lengths[i];
  7. entry.lengths[i] = 0;
  8. }
  1. redundantOpCount++;
  2. journalWriter.append(REMOVE + ’ ’ + key + ‘\n’);
  3. lruEntries.remove(key);
  1. if (journalRebuildRequired()) {
  2. executorService.submit(cleanupCallable);
  3. }
  1. return true;
  2. }
  1. /
  2. * Returns true if this cache has been closed.
  3. */
  4. public boolean isClosed() {
  5. return journalWriter == null;
  6. }
  1. private void checkNotClosed() {
  2. if (journalWriter == null) {
  3. throw new IllegalStateException(“cache is closed”);
  4. }
  5. }
  1. /
  2. * Force buffered operations to the filesystem.
  3. */
  4. public synchronized void flush() throws IOException {
  5. checkNotClosed();
  6. trimToSize();
  7. journalWriter.flush();
  8. }

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

这里我就分享一份资料,希望可以帮助到大家提升进阶。

内容包含:Android学习PDF+架构视频+面试文档+源码笔记高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 这几块的内容。分享给大家,非常适合近期有面试和想在技术道路上继续精进的朋友。

如果你有需要的话,可以点击Android学习PDF+架构视频+面试文档+源码笔记获取免费领取方式

喜欢本文的话,不妨给我点个小赞、评论区留言或者转发支持一下呗~

  1. }
  1. /
  2. * Returns true if this cache has been closed.
  3. */
  4. public boolean isClosed() {
  5. return journalWriter == null;
  6. }
  1. private void checkNotClosed() {
  2. if (journalWriter == null) {
  3. throw new IllegalStateException(“cache is closed”);
  4. }
  5. }
  1. /
  2. * Force buffered operations to the filesystem.
  3. */
  4. public synchronized void flush() throws IOException {
  5. checkNotClosed();
  6. trimToSize();
  7. journalWriter.flush();
  8. }

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-OWI0FRCb-63)]
[外链图片转存中…(img-P9DV0VpD-63)]
[外链图片转存中…(img-dzmqOyw4-63)]
[外链图片转存中…(img-mC24F0Z9-64)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-cWofcRqd-64)]

这里我就分享一份资料,希望可以帮助到大家提升进阶。

内容包含:Android学习PDF+架构视频+面试文档+源码笔记高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 这几块的内容。分享给大家,非常适合近期有面试和想在技术道路上继续精进的朋友。

如果你有需要的话,可以点击Android学习PDF+架构视频+面试文档+源码笔记获取免费领取方式

喜欢本文的话,不妨给我点个小赞、评论区留言或者转发支持一下呗~

img

小讯
上一篇 2025-01-26 15:36
下一篇 2025-03-14 07:09

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/13174.html