Picasso 상세 설명, 완벽 호 환 OkHttp 3.3, 캐 시 최적화, https 지원
왜 Fresco, Glide 가 이렇게 강 한 배경 에서 나 는 그때 의 Picasso 가 생각 났 고 왜 이 글 을 썼 을 까?최근 프로젝트 는 square 회사 의 RxAndroid, Retrfit 과 OKhttp 를 사 용 했 기 때문에 이 회사 가 Picasso 를 불 러 올 사진 이 있 었 다 는 것 을 생각 할 수 밖 에 없 었 다. 그래서 square 회사 의 온 가족 통 으로 프로젝트 개발 을 진행 했다. 개발 원 가 를 줄 이 고 APK 의 증 가 를 방지 하기 위해 한 회사 의 구조 이전에 호환성 은 걱정 하지 않 아 도 된다.그러면 피 카 스 의 길 을 돌아 보 겠 습 니 다.
우선 주류 이미지 로드 라 이브 러 리 부터 보 여 주세요.
나 는 일반 listview 로 50 장의 그림 을 불 러 오고 빠 른 미끄럼 목록 을 만 들 었 다. 다음은 glide 와 picasso 소모 메모리 그림 이다.
glide
Picasso
glide 를 좋아 하 는 친 구 는 이 글 을 볼 수 있 습 니 다.http://mrfu.me/2016/02/27/Glide_Getting_Started/
실험 테스트 를 하고 간단 한 비 교 를 한 후에 왜 Picasso 를 계속 말 해 야 합 니까? 그 가 얼마나 유창 한 지 는 말 하지 않 습 니 다. 다만 square 회사 의 다른 오픈 소스 프로젝트 를 사용 하면 그들 은 모두 okhttp 에 의존 하 는 것 을 발견 할 수 있 습 니 다. okhttp 의 강 함 은 말 할 필요 도 없습니다. 오늘 은 piacsso 와 관련 된 것 만 소개 하고 picasso (공식:https://github.com/square/picasso) 자주 사용 하 는 기술!
Picasso
\ # 사용 방법:
gradle 설정
dependencies {
c
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.squareup.okhttp3:okhttp:3.3.1'
compile 'com.squareup.okhttp3:logging-interceptor:3.3.1'
}
현재 2.5.3 은 2.52 에서 okhttp 3 를 호 환 할 수 없 는 문 제 를 복 구 했 지만 저 는 2.52 버 전 을 선 택 했 습 니 다.
기본 로드 방법
Picasso.with(getApplication())
.load(url)
.into(imageView);
이상 의 용법 은 매우 간단 합 니 다. 그림 을 불 러 올 때 url 을 imageview 에 삽입 하면 됩 니 다. picasso 의 다른 강력 한 기능 이 아직 많이 이해 되 지 않 은 학생 들 은 Follow Me!
그림 을 재단 하 다
Picasso.with(getApplication()).resize(width, height);
이 방법 은 bug, 오용!
Transformation 으로 전의 실현:
Picasso.with(getApplication())
.load(url)
.transform(new PaTransformation(width, height)).into(imageView);
Transformation 은 picasoo 가 돌아 오 는 bitmap 를 차단 하고 bitmap 을 들 고 마음대로 할 수 있 습 니 다!
public class TamicTransformation implements Transformation {
private int width;
private int height;
private String key;
public PaTransformation(int width, int height) {
this(width, height, width + "*" + height);
}
public PaTransformation(int width, int height, String key) {
this.width = width;
this.height = height;
this.key = key;
}
@Override
public Bitmap transform(Bitmap source) {
source
if (result != source) {
// Same bitmap is returned if sizes are the same
source.recycle();
}
return result;
}
@Override
public String key() {
return key;
}
}
원형 두상 처리
public class CircleTransformation implements Transformation {
private static final int STROKE_WIDTH = 5;
@Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
if (squaredBitmap != source) {
source.recycle();
}
Bitmap bitmap = Bitmap.createBitmap(size, size,source.getConfig());
Canvas canvas = new Canvas(bitmap);
Paint avatarPaint = new Paint();
BitmapShader shader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);avatarPaint.setShader(shader);
Paint outlinePaint = new Paint();
outlinePaint.setColor(Color.WHITE);
outlinePaint.setStyle(Paint.Style.STROKE);
outlinePaint.setStrokeWidth(STROKE_WIDTH);
outlinePaint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, avatarPaint);
canvas.drawCircle(r, r, r - STROKE_WIDTH / 2, outlinePaint);
squaredBitmap.recycle();
return bitmap;
}
@Override
public String key() {
return "circle)";
}
}
이어서 렌 더 링 모드 설정
Picasso.with(getApplication()) .fit().centerCrop()
캐 시 비우 기
새로운 버 전 2.52 는 이전의 cache 를 직접 가 져 올 수 없 기 때문에 Picasso. invalidate () 로 캐 시 를 선명 하 게 할 수 있 습 니 다!
예전 에 우 리 는 이렇게 할 수 있 었 다.
Clear.clearCache(Picasso.with(context));
근 데 지금 은 안 돼 요.
약간 봉 하여 이렇게 만 들 었 다.
void clearCache(Uri uri, File file, String path) {
if (!TextUtils.isEmpty(uri.toString())) {
mPicasso.invalidate(uri);
return;
}
if (!NullUtils.isNull(file)) {
mPicasso.invalidate(file);
return;
}
if (!TextUtils.isEmpty(path)) {
mPicasso.invalidate(path);
}
}
물론 그 럴 수도 있 지!
Picasso.with(getContext()).load(Url).memoryPolicy(MemoryPolicy.NO_CACHE).into(image);
그림 을 불 러 올 때 캐 시 를 하지 못 하 게 합 니 다!
캐 시 추가
물론 2.5.2 oKhttp 3.3 에 대한 호 환 을 하지 않 았 기 때문에 저 희 는 사용자 정의 cilent 를 추가 하여 okhttp 에 캐 시 맞 춤 형 을 만 들 었 습 니 다. 아래 자세 로 하 십시오.
OkHttpClient 구축
// creat the OkHttpClient.
OkHttpClient client =new OkHttpClient
.Builder()
.cache(new Cache(" ", 1000*1024))
.addInterceptor(new CaheInterceptor(context, null))
.addNetworkInterceptor(new CaheInterceptor(context, null))
.build();
차단기 인 터 셉 터
차단기 가 낯 설 지 않 습 니 다. 특히 okhttp 와 retofit 를 해 본 친구 들 은 http 의 차단 요청 과 응답 을 차단 한 것 이 분명 합 니 다.
public class CaheInterceptor implements Interceptor {
private Context context;
public CaheInterceptor(@NonNull Context context) {
this.context = context;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (NetworkUtil.isNetworkAvailable(context)) {
Response response = chain.proceed(request);
// read from cache for 60 s
int maxAge = 300;
String cacheControl = request.cacheControl().toString();
Log.e("Tamic", maxAge+ "s load cahe:" + cacheControl);
return response.newBuilder()
.removeHeader("Pragma")
.removeHeader("Cache-Control")
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
} else {
Log.e("Tamic", " no network load cahe");
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
Response response = chain.proceed(request);
//set cahe times is 3 days
int maxStale = 60 * 60 * 24 * 3;
return response.newBuilder()
.removeHeader("Pragma")
.removeHeader("Cache-Control")
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
}
}
Picasso 에 추가
// Generate the global default Picasso instance.
Picasso mPicasso = getPicasso(context, null);
mPicasso.setLoggingEnabled(true);
}
사용자 정의 Downloader
okhttp 3.31 호 환 을 위해 다운로드 기 를 실현 합 니 다!
public class ImageDownLoader implements Downloader {
OkHttpClient client = null;
public ImageDownLoader(OkHttpClient client) {
this.client = client;
}
@Override
public Response load(Uri uri, int networkPolicy) throws IOException {
CacheControl cacheControl = null;
if (networkPolicy != 0) {
if (NetworkPolicy.isOfflineOnly(networkPolicy)) {
cacheControl = CacheControl.FORCE_CACHE;
} else {
CacheControl.Builder builder = new CacheControl.Builder();
if (!NetworkPolicy.shouldReadFromDiskCache(networkPolicy)) {
builder.noCache();
}
if (!NetworkPolicy.shouldWriteToDiskCache(networkPolicy)) {
builder.noStore();
}
cacheControl = builder.build();
}
}
Request.Builder builder = new Request.Builder().url(uri.toString());
if (cacheControl != null) {
builder.cacheControl(cacheControl);
}
okhttp3.Response response = client.newCall(builder.build()).execute();
int responseCode = response.code();
if (responseCode >= 300) {
response.body().close();
throw new ResponseException(responseCode + " " + response.message(), networkPolicy,
responseCode);
}
boolean fromCache = response.cacheResponse() != null;
ResponseBody responseBody = response.body();
return new Response(responseBody.byteStream(), fromCache, responseBody.contentLength());
}
@Override
public void shutdown() {
Cache cache = client.cache();
if (cache != null) {
try {
cache.close();
} catch (IOException ignored) {
}
}
}
}
이 어 ImageDownloader 를 Picasso / * * 에 추가 하여 Big Image only, Not singleton but shared cache * / public Picasso getPicasso (Context context) {OkHttpClient client = getProgressBarClient (); return new Picasso. Builder (context). downloader (new ImageDownloader (client). build ();}
/** * Not singleton */ private OkHttpClient getProgressBarClient() { return client.newBuilder() .addInterceptor(new CaheInterceptor(context)) .addNetworkInterceptor(new CaheInterceptor(contextr)) .build(); }
이렇게 하면 우리 가 그림 을 불 러 올 때:
getPicasso(context) .load(Url).into(image)
따라서 Picasso 를 사용 하면 우 리 는 캐 시 정책 을 retrofit 에 직접 사용 할 수 있 습 니 다. 사실은 일거양득 으로 개발 원 가 를 크게 간소화 할 수 있 습 니 다!
Https 지원 방법
final OkHttpClient client = new OkHttpClient.Builder()
.protocols(Collections.singletonList(Protocol.HTTP_1_1))
.build();
final Picasso picasso = new Picasso.Builder(this)
.downloader(new Downloader(client))
.build();
Picasso.setSingletonInstance(picasso);
최적화 관련
캐 시 되 지 않 는 정책 최적화
public RequestCreator skipMemoryCache(RequestCreator requestCreator) {
return requestCreator.memoryPolicy(MemoryPolicy.NO_STORE, MemoryPolicy.NO_CACHE)
.networkPolicy(NetworkPolicy.NO_STORE, NetworkPolicy.NO_CACHE);
}
메모리 소 모 를 줄 이 고 RGB 565 인 코딩 형식 을 설정 하여 메모리 소 모 를 줄 입 니 다.
public RequestCreator cutDownMemory(RequestCreator requestCreator) {
return requestCreator.config(Bitmap.Config.RGB_565);
}
불 러 오기 취소
public class TamicImageView extends ImageView {
public TamicImageView(Context context) {
this(context, null, 0);
}
public TamicImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TamicImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
// Bitmap
setImageDrawable(null);
//
mPicasso.pauseTag(this);
}
}
그리고 많은 api 가 있 습 니 다. 예 를 들 어:
확장 로드
물론 알림 표시 줄 에 불 러 온 api 도 있 습 니 다.
알림 표시 줄 지원
into(RemoteViews remoteViews, int viewId, int notificationId,Notification notification)
widget 지원
into(RemoteViews remoteViews, int viewId, int[] appWidgetIds)
첫 번 째 는 원 격 보기, 두 번 째 view Id 세 번 째 는 widget id 배열 입 니 다.
미리 불 러 오기
반환 값 이 있 음
Picasso.with(context).load(url).get()
이 api 는 disk 와 메모리 에 그림 을 미리 불 러 오고 반환 값 Bitmap 이 있 습 니 다. 이 api 는 동기 화 되 어야 합 니 다. UI 메 인 스 레 드 로 호출 할 수 없습니다. 보통 view pager 에서 뒤의 index 그림 을 미리 불 러 오 거나 대상 bitmap 를 미리 가 져 와 서 업무 수행 을 하거나 일부 효과 처 리 를 할 수 있 습 니 다.
반환 값 없 음
Picasso.with(context).load(url).fetch()
그림 을 미리 불 러 오 는 기능 도 있 습 니 다. 이 api 는 메 인 스 레 드 에서 호출 할 수 있 습 니 다. 주로 callback 이 실현 되 고 실패 와 성공 함 수 를 상부 에서 호출 할 수 있 습 니 다. 그러나 가 져 올 수 없 는 그림 자원 을 불 러 옵 니 다.
public static class EmptyCallback implements Callback {
@Override public void onSuccess() {
}
@Override public void onError() {
}
}
}
불 러 오기 취소
주로 위의 세 가지 방식 으로 첫 번 째 는 알 수 없 는 생각 입 니 다. 바로 특정한 view 의 로 딩 요청 을 취소 하 는 것 입 니 다. 보통 우 리 는 activity 가 사망 할 때 호출 합 니 다. 세 번 째 방법 은 우리 가 지정 한 로 딩 action 을 취소 하 는 것 입 니 다. 예 를 들 어 한 번 로 딩 에 picasso 의 Picasso. with (context). tag () 를 설정 할 때 cancelTag ("tag") 를 사용 할 수 있 습 니 다.지정 한 요청 을 취소 하려 면 마지막 으로 무엇 입 니까? 그 는 태그 의 포장 류 Target 에 가입 하여 리 셋 요청 처 리 를 해 야 합 니 다. 개발 자 상부 에서 취소 절차 에 대한 통 제 를 편리 하 게 해 야 합 니 다.
mPicasso.cancelRequest(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom afrom) {
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
알림 표시 줄 그림 에 대한 취소 인터페이스 도 있 습 니 다.
cancelRequest(RemoteViews remoteViews, int viewId)
알림 표시 줄 의 VIEW 는 모두 가 잘 알 고 있 습 니 다. 모두 RemoteViews 로 전환 하여 보 여 줍 니 다. 그러면 cancel 에 게 알 릴 때 이 취소 방법 을 직접 호출 할 수 있 습 니 다.
후기
한 마디 로 하면 picasso 가 가장 빠 른 그림 로드 프레임 워 크 는 아니 지만 그 는 기본 적 인 로 컬 과 인터넷 그림 을 로드 하 는 토대 에서 우리 로 하여 금 자신의 확장 능력 을 잘 제공 할 수 있 습 니 다. 그 확장 성과 적응성 이 더욱 강하 고 ohttp + rxJava + Picasso 를 결합 한 후에 그 가 확실히 당신 에 게 적합 하 다 는 것 을 알 게 될 것 입 니 다. 만약 에 glide 를 좋아한다 면 이 완벽 한 글 을 보 세 요: glide 시리즈튜 토리 얼
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Picasso 상세 설명, 완벽 호 환 OkHttp 3.3, 캐 시 최적화, https 지원왜 Fresco, Glide 가 이렇게 강 한 배경 에서 나 는 그때 의 Picasso 가 생각 났 고 왜 이 글 을 썼 을 까?최근 프로젝트 는 square 회사 의 RxAndroid, Retrfit 과 OKhtt...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.