Picasso를 사용하여 비트 맵으로 콜백 받기


83

Picasso 를 사용하여 내 앱의 이미지를 다운로드하고 있습니다.

.NET Framework에 Bitmap로드되기 전에 첫 번째 파일 에 액세스해야하는 상황에 있습니다 ImageView. Downloader.Response수업 의 존재 는 이것이 가능하다는 것을 암시하는 것처럼 보이지만 사용 예를 찾을 수 없습니다. 피카소로 할 수 있다면이 특정한 경우를 비동기 적으로 처리하기 위해 더 많은 코드를 작성하고 싶지 않습니다.

누구든지 방법을 보여줄 수 있습니까?


답변:


172

누군가 궁금해하는 경우 github에서 답변을 찾았습니다.

private Target target = new Target() {
      @Override
      public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
      }

      @Override
      public void onBitmapFailed(Drawable errorDrawable) {
      }

      @Override
      public void onPrepareLoad(Drawable placeHolderDrawable) {
      }
}

private void someMethod() {
   Picasso.with(this).load("url").into(target);
}

@Override 
public void onDestroy() {  // could be in onPause or onStop
   Picasso.with(this).cancelRequest(target);
   super.onDestroy();
}

이 게시물은 익명 콜백을 사용하지 않고 대신 대상에 인스턴스 변수를 사용하도록 권장합니다.


30
이상적으로 Target는 뷰 또는 뷰 홀더 객체에서 직접 구현 하는 것이 좋습니다 . 이렇게하지 않으면 인스턴스에 대한 강력한 참조를 어딘가에 유지해야합니다. 그렇지 않으면 가비지 수집됩니다.
Jake Wharton

@JakeWharton :의 모든 항목에 사용자 지정 애니메이션을 적용하려면 ListView다음과 같이하는 것이 좋습니다 private static ViewHolder { private ImageView imageView; private Target target = new Target() { public void onBitmapLoaded() { // do animation on imageView } } }.
mbmc

@JakeWharton 은 마지막 댓글 에서 github.com/square/picasso/issues/308 에서 설명합니다 .
toobsco42 2014

8
onBitmapLoaded가 onPrepareLoad 이후 처음 호출되지 않음
Amit Thaper 2014 년

예를 들어 주셔서 감사합니다. 나는 onDestroy에서 슈퍼 콜을 놓치고 있습니다.
Ben Groot 2014 년

69

여기 에서 가져온 :

Picasso.with(this)
    .load(url)
    .into(new Target() {
        @Override
        public void onBitmapLoaded (final Bitmap bitmap, Picasso.LoadedFrom from){
            /* Save the bitmap or do something with it here */

            //Set it in the ImageView
            theView.setImageBitmap(bitmap); 
        }
});

업데이트 됨 (2016 년 5 월 4 일) :

            Picasso.with(this)
                .load(youUrl)
                .into(new Target() {
                    @Override
                    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {

                    }

                    @Override
                    public void onBitmapFailed(Drawable errorDrawable) {

                    }

                    @Override
                    public void onPrepareLoad(Drawable placeHolderDrawable) {

                    }
                });

업데이트 됨 (2016 년 11 월 22 일)

또는 강력한 참조를 사용하여 Target가비지 수집되지 않도록

Target target = new Target() {
            @Override
            public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {

            }

            @Override
            public void onBitmapFailed(Drawable errorDrawable) {

            }

            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {

            }
        };


void foo() {
        Picasso.with(getContext()).load(getUrl()).into(target);
}

Kotlin

object: com.squareup.picasso.Target {
                  override fun onBitmapFailed(e: java.lang.Exception?, errorDrawable: Drawable?) {
                    TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
                }

                  override fun onPrepareLoad(placeHolderDrawable: Drawable?) {
                    TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
                  }

                  override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) {

                  }
                }

6
익명 대상은 쓰레기 수집 할 수
스티브 M

@SteveM 그리고 그것은 무엇을할까요? 요청을 취소 하시겠습니까? 비트 맵이로드되지 않도록 하시겠습니까?
nurettin

@nurettin 나는 Picasso (또는 Glide)가 대상에 대한 일종의 약한 참조를 가지고 있다고 가정하고 있습니다. 따라서 익명의 경우 하드 참조가 없으며 GC에 취약합니다. Picasso가 참조를 확인할 때 null이되어 콜백이 호출되지 않습니다.
Steve M

따라서이 솔루션은 GC가 때때로 콜백의 로딩과 호출 사이에서 실행되어 콜백이 호출되지 않도록 할 수 있기 때문에 정말 좋지 않습니다.
Steve M

@SteveM 나는 어떤 인스턴스에서든 적어도 2000 명의 사용자와 함께 목록보기를 스크롤하는 동안 아이콘을로드하는 애플리케이션을 Google Play에서 호스팅하고이 방법을 사용하여 일부 아이콘의 크기를 조정했지만 불만 사항을 보지 못했습니다. 나는 많은) 또는 아이콘이로드되지 않는 충돌 보고서를 얻습니다. 따라서 적어도 일화 적으로, 어떤 이유로 가비지 수집되지 않습니다.
nurettin

7

다음보다 쉬울 수있는 것 :

val url: String = "https://...."
val bitmap: Bitmap = Picasso.with(context).load(url).get()

메인 스레드가 아닌 곳에서 호출해야합니다!

또는 RxJava 2 사용 :

fun getBitmapSingle(picasso: Picasso, url: String): Single<Bitmap> = Single.create {
    try {
        if (!it.isDisposed) {
            val bitmap: Bitmap = picasso.load(url).get()
            it.onSuccess(bitmap)
        }
    } catch (e: Throwable) {
        it.onError(e)
    }
}

비트 맵 검색 :

getBitmapSingle(Picasso.with(context), "https:/...")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({ bitmap ->
                // val drawable = BitmapDrawable(context, bitmap)
                }, Throwable::printStackTrace)

Picasso v.2.5.2를 사용했습니다.


2

나는 당신 중 일부가 위 답변의 RxJava 버전을 원할 것이라고 생각했습니다 ... 여기 있습니다.

    public static Observable<Bitmap> loadBitmap(Picasso picasso, String imageUrl) {
    return Observable.create(new Observable.OnSubscribe<Bitmap>() {
        @Override
        public void call(Subscriber<? super Bitmap> subscriber) {
            Target target = new Target() {
                @Override
                public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                    subscriber.onNext(bitmap);
                    subscriber.onCompleted();
                }

                @Override
                public void onBitmapFailed(Drawable errorDrawable) {
                    subscriber.onError(new Exception("failed to load " + imageUrl));
                }

                @Override
                public void onPrepareLoad(Drawable placeHolderDrawable) {
                }
            };
            subscriber.add(new Subscription() {
                private boolean unSubscribed;

                @Override
                public void unsubscribe() {
                    picasso.cancelRequest(target);
                    unSubscribed = true;
                }

                @Override
                public boolean isUnsubscribed() {
                    return unSubscribed;
                }
            });
            picasso.load(imageUrl).into(target);
        }
    });
}

추신 : 구독 할 때 활동에 대한 구독 참조를 저장하십시오. 그렇지 않으면 응답을 받기 전에 대상이 GC됩니다.


이 코드가 최신 RxAndroid에서 작동하지 않는 것 같습니다
Pavandroid
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.