Android 는 로 컬 앨범 사진 을 많이 불 러 오 는 것 을 최적화 합 니 다.
최적화 조회 앨범 사진 을 설명 하기 전에 우 리 는 먼저 PM 이 제기 한 수 요 를 살 펴 보 자.PM 의 수 요 는 매우 간단 하 다.바로 위 챗 과 유사 한 로 컬 앨범 사진 조회 컨트롤 을 하 는 것 이다.주로 두 부분 을 포함한다.
4.567917.사진 선택 페이지 에 들 어가 면 핸드폰 에 있 는 모든 사진 을 표시 해 야 한다.시스템 앨범 사진 과 다른 디 렉 터 리 에 있 는 모든 사진 을 포함 하고 시간 에 따라 거꾸로 배열 해 야 한다4.567917.앨범 기능 을 전환 하고 앨범 페이지 를 전환 하여 핸드폰 에 있 는 모든 그림 디 렉 터 리 목록 을 표시 하 며 각 디 렉 터 리 에 있 는 모든 그림 갯 수 와 표지 그림 을 표시 합 니 다이 두 가지 수 요 는 간단 해 보이 지만 사실은 일련의 성능 최적화 문 제 를 숨 기 고 있다.최적화 하기 전에 우 리 는 다른 유명한 app 이 대량의 그림 을 불 러 오 는 성능 표현(gif 녹화 가 뚜렷 하지 않 지만 전시 문 제 는 충분 하 다)을 조사 연 구 했 습 니 다.
다음은 몇 가지 상용 소프트웨어 를 테스트 하 였 다.
위 챗:
위 챗 의 이미지 조회 속 도 는 매우 빠르다.기본적으로 이미지 선택 페이지 에 들 어가 면 앨범 데 이 터 는 이미 찾 아 냈 다.각 이미지 디 렉 터 리 아래 그림 의 개수 와 표지 그림 의 url 을 포함 하여 이 체험 은 비교적 좋다.
시 나 웨 이 보:
위 챗 과 비교 해 보면 시 나 웨 이 보가 하 는 체험 은 비교적 좋 지 않다.사진 선택 페이지 에 들 어간 후에 먼저 검은색 화면 이 고 그 다음 에 흰색 화면 이다.진도 가 하나 도 없어 서 사용 자 는 app 이 죽 었 다 고 생각 하고 시간 이 지나 서 야 나타 나 는데 이 체험 은 비교적 나쁘다.
QQ:
QQ 가 올 라 오 자마자 최근 100 장의 사진 을 불 러 왔 습 니 다.이 속 도 는 매우 빠 릅 니 다.하지만 Camera 앨범(5000 여 장)에 들 어간 후에 진도 표 가 기다 리 고 있 습 니 다.저 는 체험 해 보 았 습 니 다.기다 리 는 시간 이 비교적 길 었 습 니 다.이 체험 은 시 나 웨 이 보 보다 조금 좋 고 위 챗 보다 못 합 니 다.
한어:
한 어 는 가장 못 만 든 것 이다.올 라 오 면 4,5 초 걸 리 고 그 다음 에 검 은 화면 이 2,3 초 걸 려 서 야 나 타 났 다.
2.종합 대비
종합 적 인 대 비 를 거 친 후에 위 챗 은 잘 만 들 었 습 니 다.기본적으로 앨범 페이지 에 들 어가 면 모든 사진 을 보 여줄 수 있 고 앨범 목록 도 매우 빨리 보 여 줍 니 다!!!
우리 의 조사 연 구 를 통 해 위 챗 은 순환 페이지 로 딩 전략 을 사용 하 는 것 을 발견 했다.우리 의 최적화 사고 도 이런 전략 을 사용 하고 최적화 후의 효과 도 를 먼저 본다.
그림 선택 페이지 에 들 어가 면 그림 이 매우 빨리 표 시 됩 니 다.앨범 교체 페이지 에 들 어가 면 그림 디 렉 터 리 도 매우 빨리 표 시 됩 니 다.여 기 는 위 챗 처럼 그림 디 렉 터 리 를 만 드 는 캐 시 가 없습니다.하 나 는 조회 속도 가 매우 빠 르 기 때문에 기본적으로 2 초 도 안 되 어 추가 되 었 습 니 다.다른 하 나 는 실시 간 으로 앨범 의 최신 데 이 터 를 새로 고 칠 수 있 습 니 다.
각 앨범 목록 을 자주 전환 하면 사진 이 매우 빠르게 조회 되 고 체험 도 좋 습 니 다!!
3.최적화 실현
앨범 디 렉 터 리 최적화 조회
모든 앨범 디 렉 터 리 목록 을 열거 해 야 하기 때문에 여 기 는 다른 좋 은 방법 이 없습니다.ContentResolver 의 query 방법 에 직접 문의 하 십시오.여 기 는 조 회 를 가속 화하 기 위해 while 순환 에서 시간 이 걸 리 는 판단 을 없 애고 이미지 판단 여 부 를 검사 하 는 논 리 를 밖으로 옮 기 고 구체 적 으로 사용 할 때 판단 합 니 다.
그림 조회 URI
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
그림 url 과 그림 이 있 는 디 렉 터 리 만 조회 하기 때 문 입 니 다.
String[] projection = {MediaStore.Images.ImageColumns.DATA, MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME};
PM 은 앨범 을 그림 의 시간 에 따라 거꾸로 배열 하도록 요구한다.그림 의 생 성,수정 은 그 가 있 는 디 렉 터 리 의 정렬 에 영향 을 주 고 정렬 은 시간 에 따라 거꾸로 배열 한다.
String sortOrder = MediaStore.Images.Media.DATE_TAKEN + " DESC ";
이러한 검색 조건 에 따라 query 를 거 친 후에 Cursor 를 얻 을 수 있 습 니 다.이 cursor 에는 우리 가 필요 로 하 는 모든 그림 의 정보 가 포함 되 어 있 습 니 다.그리고 우 리 는 while 순환 으로 이 cursor 를 옮 겨 다 니 며 while 순환 에서 시간 을 소모 해 서 는 안 됩 니 다.
// ,
HashSet<String> dirPaths = new HashSet<String>();
while (cursor.moveToNext()) {
//
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA));
String bucketName = cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME));
if (TextUtils.isEmpty(allFolderItem.coverImagePath)) {
allFolderItem.coverImagePath = path;
}
File parentFile = new File(path).getParentFile();
if (parentFile == null) continue;
String dirPath = parentFile.getAbsolutePath();
PicFolderItem folderItem = null;
// HashSet ( , ~~)
if (dirPaths.contains(dirPath)) {
continue;
} else {
dirPaths.add(dirPath);
boolean isNew = true;
// dirPath , bucketName
for (PicFolderItem item : picList) {
if (item.name.equals(bucketName)) {
folderItem = item;
item.addParentPath(dirPath);
isNew = false;
break;
}
}
if (isNew) {
folderItem = new PicFolderItem();
folderItem.coverImagePath = path;
folderItem.name = bucketName;
folderItem.addParentPath(dirPath);
}
}
String[] array = parentFile.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
if (filename.endsWith(".jpg")
|| filename.endsWith(".png")
|| filename.endsWith(".jpeg"))
return true;
return false;
}
});
int arrayCount = array == null ? 0 : array.length;
folderItem.count += arrayCount;
if (!picList.contains(folderItem) && arrayCount > 0) {
picList.add(folderItem);
}
}
이렇게 하면 휴대 전화의 모든 사진 목록,디 렉 터 리 의 사진 장수 와 표지 그림 url 을 매우 빠르게 조회 할 수 있다.여 기 는 주로 세 가 지 를 최적화 시 켰 다.while 순환 중 소모 시간 제거 판단
이전 코드 에는 파일 그림 이 존재 하 는 지 판단 하 는 코드 가 있 습 니 다.
public static boolean isFileExist(String path) {
File file = new File(path);
if (file == null || !file.exists()) {
return false;
}
return true;
}
이 코드 를 while 순환 에 넣 는 것 은 매우 무 서운 것 이다.내 가 테스트 해 보 니 5000 여 장의 그림 을 모두 검사 하려 면 총 시간 이 3,4 초 증가 할 것 이다.이 판단 은 밖으로 내 보 내 고 어떤 그림 을 구체 적 으로 조작 할 때 구체 적 인 업무 판단 을 할 수 있 습 니 다!그림 폴 더 가 여러 번 검색 되 는 것 을 방지 합 니 다.
스 캔 한 그림 디 렉 터 리 를 저장 하기 위해 변 수 를 추가 하 였 습 니 다.스 캔 한 것 은 처리 되 지 않 습 니 다.
// ,
HashSet<String> dirPaths = new HashSet<String>();
이 최 적 화 된 후에 도 효과 가 매우 뚜렷 하 다.같은 디 렉 터 리 는 여러 번 스 캔 하지 않 을 것 이다!그림 디 렉 터 리 아래 그림 갯 수 가 져 오기
String[] array = parentFile.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
if (filename.endsWith(".jpg")
|| filename.endsWith(".png")
|| filename.endsWith(".jpeg"))
return true;
return false;
}
});
이 file.list()방법 내 부 는 native 방법 으로 조회 효율 이 매우 빠 릅 니 다!!물론 어떤 디 렉 터 리 에 있 는 그림 을 가 져 오 는 데 몇 장 이 있 는 지 cursor 를 통 해 조회 할 수 있 습 니 다!!
어떤 앨범 목록 에 있 는 모든 사진 을 조회 합 니 다.
검색 목록 아래 의 사진 을 소개 하기 전에 우 리 는 먼저 우리 가 사진 을 조회 하 는 두 가지 전략 을 소개 합 니 다.하 나 는 목록 아래 의 사진 이 비교적 많 고 걸핏하면 수천 수만 장 에 달 하 는 것 입 니 다.다른 하 나 는 그런 목록 아래 의 그림 이 비교적 적은 데,단지 몇 백 장의 그림 이다.
로 딩 정책
디 렉 터 리 아래 그림 의 수량 이 1000 장 보다 적 을 때 file.list 라 는 native 방법 으로 모든 그림 을 한 번 에 불 러 옵 니 다.이 native 는 조회 효율 이 매우 빠 르 고 수천 장의 그림 을 초 단위 로 조회 합 니 다.
순환 페이지 로드 정책
그림 의 수량 이 1000 장 이상 일 때 순환 페이지 로 딩 전략 을 사용 합 니 다.이런 전략 은 그림 의 수량 이 매우 많은 상황 에 착안 하여 페이지 를 나 누 는 방식 으로 먼저 첫 페이지 의 그림 을 불 러 와 서 사용자 가 최신 그림 을 첫눈 에 볼 수 있 도록 한 다음 에 배경 에서 다른 단계 로 다음 페이지 의 그림 을 조회 하고 모든 그림 이 조회 가 완 료 될 때 까지 합 니 다.이것 도 위 챗 의 앨범 조회 전략 이다.
로 딩 정책 구현
다음 에 정책 구현 코드 를 불 러 오 는 것 을 보 겠 습 니 다.먼저 File 의 list 방법 을 통 해 접 두 사 를 그림 형식의 파일 로 걸 러 내 고 그림 경로 배열 을 되 돌려 줍 니 다.
File dirFile = new File(dir);
String[] list = dirFile.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
if (filename.endsWith(".jpg") || filename.endsWith(".png")
|| filename.endsWith(".jpeg"))
return true;
return false;
}
});
우리 가 원 하 는 것 은 시간 에 따라 거꾸로 배열 하 는 배열 이기 때문에 위 에서 조회 한 배열 을 정렬 해 야 합 니 다.여 기 는 File 파일 last Modified 방법 을 사 용 했 습 니 다.
Collections.sort(strings, new Comparator<String>() {
@Override
public int compare(String lhs, String rhs) {
Long time1 = new File(lhs).lastModified();
Long time2 = new File(rhs).lastModified();
return time2.compareTo(time1);
}
});
순환 페이지 로드 정책 구현이 정책 은 위 챗 을 참고 하여 페이지 를 나 누 는 방식 으로 모든 그림 을 불 러 올 때 까지 한 페이지 씩 불 러 옵 니 다.
여기 서 핵심 은 검색 조건 입 니 다.검색 할 디 렉 터 리 를 검색 매개 변수 에 추가 하 는 것 입 니 다.
String selection = MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME + " = '" + + "' ";
이 selection 은 반드시 잘못 써 서 는 안 된다.그렇지 않 으 면 조회 할 수 없다.페이지 를 나 누 어야 하기 때문에 sortOrder 는 간단하게 시간 에 따라 거꾸로 배열 하 는 것 이 아니다.
String sortOrder = MediaStore.Images.Media.DATE_TAKEN + " DESC limit " + PAGE_SIZE + " offset " + pageIndex * PAGE_SIZE;
마지막 으로 Cursor 를 순환 해서 우리 가 원 하 는 그림 경 로 를 가 져 옵 니 다.PAGE_SIZE 는 상수 입 니 다.우리 가 한 번 에 몇 개 를 조회 해 야 하 는 지 를 표시 합 니 다.우 리 는 200 개 로 정 했 습 니 다.한 번 에 200 개의 데 이 터 를 조회 하고 pageIndex 는 몇 페이지 를 조회 하 는 것 입 니 다.0 부터 시작 합 니 다.
처음에 첫 페이지 의 데 이 터 를 조회 할 때 조회 한 데이터 목록 의 크기 가 우리 가 조회 하고 자 하 는 PageSize 보다 크 면 다음 페이지 가 있다 고 생각 합 니 다.pageIndex 에 1 을 더 해서 다음 페이지 를 조회 합 니 다.조회 목록 의 크기 가 PageSize 보다 작 을 때 까지.
위의 몇 단계 최 적 화 를 거 친 후에 로 컬 앨범 사진 을 불 러 오 는 것 은 기본적으로 아무런 문제 가 없다.우 리 는 실제 컴퓨터 테스트 를 통 해 사진 5549 장 을 모두 신속하게 조회 할 수 있 는데 마치 위 챗 과 갤러리 와 같다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.