Android 캐 시 DiskLRuCache 디스크 캐 시 사용

디 스 크 루 캐 시 는 루 캐 시 와 달리 루 캐 시 는 메모리 캐 시 이 고,디 스 크 루 캐 시 는 디스크 캐 시 를 말 하 는데,말 그대로 파일 을 디스크,즉 휴대 전화의 메모리 카드 에 캐 시 하 는 것 이다.다음은 DiskLruCache 의 사용법 을 간단히 소개 하 겠 습 니 다.
원본 코드 다운로드
DiskLruCache 는 SDK 에 존재 하지 않 지만 구 글 이 제창한다.그래서 우 리 는 먼저 DiskLruCache 의 소스 코드 를 다운로드 해 야 한다.
우 리 는 아래 의 이 주 소 를 통 해 원본 코드 를 다운로드 할 수 있다https://github.com/JakeWharton/DiskLruCache/tree/master/src/main/java/com/jakewharton/disklrucache
그리고 소스 코드 중의 세 가지 종 류 를 공사 에 복사 합 니 다.
DiskLruCache 상용 방법:
방법.
비고
DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
캐 시 디 렉 터 리 를 엽 니 다.없 으 면 먼저 만 듭 니 다.directory:데이터 캐 시 주소 appVersion:APP 버 전 번 호 를 지정 합 니 다.버 전 번호 가 바 뀌 면 캐 시 데 이 터 는 valueCount 가 삭 제 됩 니 다.같은 key 는 몇 개의 파일 max Size 에 대응 할 수 있 습 니까?최대 캐 시 가능 한 수량 입 니 다.
Editor edit(String key)
key 를 통 해 DiskLruCache.Editor 를 얻 을 수 있 습 니 다.Editor 를 통 해 출력 흐름 을 얻 고 로 컬 저장 소 에 캐 시 할 수 있 습 니 다.
void flush()
파일 시스템 에 버퍼 파일 저장
Snapshot get(String key)
key 값 으로 스냅 샷 을 가 져 옵 니 다.스냅 샷 이 존재 하면 LRU 대기 열의 머리 로 이동 합 니 다.스냅 샷 을 통 해 입력 스 트림 을 가 져 옵 니 다.
long size()
캐 시 데이터 의 크기,단 위 는 byte 입 니 다.
boolean remove(String key)
key 값 에 따라 해당 하 는 데 이 터 를 삭제 합 니 다.이 데이터 가 편집 되 고 있 으 면 삭제 할 수 없습니다.
void delete()
캐 시 를 닫 고 디 렉 터 리 에 있 는 모든 캐 시 데 이 터 를 삭제 합 니 다.DiskLruCache 캐 시 에서 이 디 렉 터 리 에 있 는 데이터 가 아니 더 라 도.
void close()
DiskLruCache 를 닫 으 면 캐 시 데 이 터 는 외부 저장 소 에 저 장 됩 니 다.
boolean isClosed()
DiskLruCache 가 닫 혔 는 지 판단 하고 true 로 돌아 가면 닫 혔 음 을 표시 합 니 다.
File getDirectory()
캐 시 데이터 의 디 렉 터 리
캐 시 대상 초기 화
다음은 DiskLruCache 의 간단 한 방법 을 구체 적 으로 소개 한다.먼저,우 리 는 특정한 종 류 를 사용 할 때 보통 그 구조 방법 을 먼저 찾 지만 우 리 는 이 종 류 는 final 류 로 계승 되 지 못 하고 구조 방법 은 개인 적 인 방법 이 므 로 수 동 으로 호출 할 수 없다 는 것 을 발견 했다.

public final class DiskLruCache implements Closeable {

 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_TEMP);
  this.journalFileBackup = new File(directory, JOURNAL_FILE_BACKUP);
  this.valueCount = valueCount;
  this.maxSize = maxSize;
 }

그래서 DiskLruCache 를 초기 화 할 때 open 방법 을 사용 합 니 다.

 //       ,1.        2.    3.           ,4.     ,10 * 1024 * 1024 = 10M
      DiskLruCache diskLruCache = DiskLruCache.open(getCachFile(context, uniqueName), 1, 1, cacheSize);

/**
   *       
   *
   * @param context
   * @param uniqueName          
   */
  private File getCachFile(Context context, String uniqueName) {
    String catchPath;
    //    ,           ,           
    if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) {
      catchPath = context.getExternalCacheDir().getPath();
    } else {
      catchPath = context.getCacheDir().getPath();
    }
    return new File(catchPath + File.separator + uniqueName);
  }

네 개의 인 자 를 입력 해 야 합 니 다:
File directory:sdcard 캐 시 디 렉 터 리.
  • int appVersion:버 전 번호,일반 전송 1
  • int value Count:캐 시 된 데 이 터 는 key 에 대응 하여 하나의 key 가 몇 개의 데 이 터 를 대응 하 는 지 나타 내 고 보통 1 을 전달 하면
  • long maxSiz:캐 시 크기 10*1024*1024=10Msdcard 캐 시 디 렉 터 리 에 들 어 갈 때 sdcard 가 존재 하 는 지,sdcard 가 제거 되 고 있 는 지 확인 하 십시오.이 두 가지 상황 이 라면캐 시 디 렉 터 리 는 getCacheDir().getPath()로 설정 합 니 다.메모리 에 캐 시 합 니 다.
    캐 시 에 쓰기
    캐 시 초기 화 완료 후 캐 시 에 기록 합 니 다.이 럴 때 인터넷 에서 그림 을 다운로드 해 야 합 니 다.
    
    new Thread() {
              @Override
              public void run() {
                DiskLruCache.Editor editor = null;
                try {
                  //   Editor   
                  editor = diskLruCache.edit(hashKeyForDisk(url));
                  if (editor != null) {
                    //     
                    OutputStream outputStream = editor.newOutputStream(0);
                    //url            
                    //outputStream      ,
                    //          ,              ,
                    //    ,           。
                    if (downloadUrlToStream(url, outputStream)) {
                      editor.commit();
                    } else {
                      //     
                      editor.abort();
                    }
                    diskLruCache.flush();
                  }
    
                } catch (Exception e) {
                  e.printStackTrace();
                }
    
              }
            }.start();
    
    
    
     /**
       *  key    
       *
       * @param key
       * @return
       */
      public String hashKeyForDisk(String key) {
        String cacheKey;
        try {
          final MessageDigest mDigest = MessageDigest.getInstance("MD5");
          mDigest.update(key.getBytes());
          cacheKey = bytesToHexString(mDigest.digest());
        } catch (NoSuchAlgorithmException e) {
          cacheKey = String.valueOf(key.hashCode());
        }
        return cacheKey;
      }
    
      private String bytesToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
          String hex = Integer.toHexString(0xFF & bytes[i]);
          if (hex.length() == 1) {
            sb.append('0');
          }
          sb.append(hex);
        }
        return sb.toString();
      }
    먼저 DiskLruCache.Editor editor 대상 을 초기 화하 고 그림 의 url 을 MD5 암호 화 한 다음 캐 시 그림 의 key 로 사용 합 니 다.여 기 는 왜 url 을 key 로 직접 사용 하지 않 고 md5 암호 화 를 해 야 합 니까?url 에 특수 문자 가 존재 할 수 있 기 때문에 파일 이름 을 지 을 때 비합법적 일 수 있 습 니 다.md5 암호 화 된 문 자 는 유일 하 며 0-F 문자 입 니 다.그리고 OutputStream outputStream 대상 만 들 기
    
    OutputStream outputStream = editor.newOutputStream(0);
    그림 을 다운로드 한 후 이 출력 흐름 을 통 해 파일 을 기록 합 니 다.즉,다운로드 한 그림 을 캐 시 디 렉 터 리 에 기록 하 는 것 입 니 다.
    
     //    ,           。
                    if (downloadUrlToStream(url, outputStream)) {
                      editor.commit();
                    } else {
                      //     
                      editor.abort();
                    }
                    diskLruCache.flush();
    
    다운로드 성공 후 editor.comit()호출 하기;제출 하면 됩 니 다.
    사진 을 다운로드 하 는 방법 을 구체 적 으로 살 펴 보 겠 습 니 다.
    
    /**
       *         ,      
       *
       * @param urlString
       * @param outputStream
       * @return
       */
      private boolean downloadUrlToStream(String urlString, OutputStream outputStream) {
        HttpURLConnection urlConnection = null;
        BufferedOutputStream out = null;
        BufferedInputStream in = null;
        try {
          final URL url = new URL(urlString);
          urlConnection = (HttpURLConnection) url.openConnection();
          in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024);
          out = new BufferedOutputStream(outputStream, 8 * 1024);
          int b;
          while ((b = in.read()) != -1) {
            out.write(b);
          }
          return true;
        } catch (final IOException e) {
          e.printStackTrace();
        } finally {
          if (urlConnection != null) {
            urlConnection.disconnect();
          }
          try {
            if (out != null) {
              out.close();
            }
            if (in != null) {
              in.close();
            }
          } catch (final IOException e) {
            e.printStackTrace();
          }
        }
        return false;
      }
    
    우 리 는 다운로드 한 그림 이 OutputStream outputStream 에 쓰 여 있 는 것 을 보 았 다.즉,캐 시 에 쓰 여 있 는 것 이다.이렇게 되자 그림 을 캐 시 에 썼 다.
    캐 시 그림 의 디 렉 터 리 를 보 겠 습 니 다:

    우 리 는 여기 journal 파일 과 이름 이 긴 파일 이 있 는 것 을 보 았 습 니 다.이름 이 긴 파일 은 바로 우리 의 캐 시 파일 입 니 다.md5 암호 화 된 문자열 이기 때 문 입 니 다.
    캐 시 읽 기
    다음은 캐 시 파일 을 읽 는 방법 을 소개 합 니 다.
    
     DiskLruCache.Snapshot snapshot = diskLruCache.get(hashKeyForDisk(url));
            if(snapshot!=null){
              InputStream inputStream = snapshot.getInputStream(0);
              Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
              //     ,         bitmap
              imageView.setImageBitmap(bitmap); 
            }
    
    여기 가 왜 getInputStream(0)입 니까?네?키 가 대응 하 는 데 이 터 를 정 의 했 기 때문에 0 번 만 가 져 오 면 됩 니 다.
    우 리 는 실행 중인 효과 도 를 봅 시다.

    캐 시 제거
    reove 방법 을 호출 하여 지정 한 데 이 터 를 제거 합 니 다.
    
    public synchronized boolean remove(String key) throws IOException 
    기타 api
    1.flush()
    메모리 의 조작 기록 을 로그 파일,즉 sdcard 의 journal 파일 에 동기 화 하 는 데 사용 합 니 다.DiskLruCache 가 정상적으로 작 동 하려 면 이 파일 의 내용 에 의존 해 야 합 니 다.하지만 캐 시 작업 을 쓸 때마다 한 번 씩 호출 할 필 요 는 없습니다.보통 Activity 의 onPause 방법 에서 한 번 호출 하면 됩 니 다.
    2.delete()
    모든 캐 시 삭제
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기