마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

비트맵 이미지를 받아서 recyclerview로 넘겨주고 싶습니다.

0 추천

구글에서 사진을 받아와서 recyclerview로 넘겨주는 작업을 하고싶습니다.

public void sendPlacedata(){
    myDataset.clear();

    for(int i =0; i < IDarrayList.size(); i++) {
        final String PID = IDarrayList.get(i);
        Places.GeoDataApi.getPlaceById(mGoogleApiClient, PID)
                .setResultCallback(new ResultCallback<PlaceBuffer>() {
                    @Override
                    public void onResult(PlaceBuffer place) {
                        if (place.getStatus().isSuccess() && place.getCount() > 0) {
                            final com.google.android.gms.location.places.Place myPlace = place.get(0);

                            new PhotoTask(mRecyclerView.getWidth(), mRecyclerView.getHeight()).execute(PID);
                            myDataset.add(new mainitem(GoogleImage));

for문으로 PlaceId 별로 이미지를 받아와서 넘겨주는 방식인데요

private class PhotoTask extends AsyncTask<String, Void, PhotoTask.AttributedPhoto> {

    private int mHeight;
    private int mWidth;

    public PhotoTask(int width, int height) {
        mHeight = height;
        mWidth = width;
    }


    @Override
    protected AttributedPhoto doInBackground(String... params) {
        if (params.length != 1) {
            return null;
        }
        final String placeId = params[0];
        AttributedPhoto attributedPhoto = null;

        PlacePhotoMetadataResult result = Places.GeoDataApi
                .getPlacePhotos(mGoogleApiClient, placeId).await();

        if (result.getStatus().isSuccess()) {
            PlacePhotoMetadataBuffer photoMetadataBuffer = result.getPhotoMetadata();
            if (photoMetadataBuffer.getCount() > 0 && !isCancelled()) {
                // Get the first bitmap and its attributions.
                PlacePhotoMetadata photo = photoMetadataBuffer.get(0);
                CharSequence attribution = photo.getAttributions();
                // Load a scaled bitmap for this photo.
                Bitmap image = photo.getScaledPhoto(mGoogleApiClient, mWidth, mHeight).await()
                        .getBitmap();

                attributedPhoto = new AttributedPhoto(attribution, image);
            }
            // Release the PlacePhotoMetadataBuffer.
            photoMetadataBuffer.release();
        }
        return attributedPhoto;
    }

    @Override
    protected void onPostExecute(AttributedPhoto attributedPhoto) {
        if (attributedPhoto != null) {
            // Photo has been loaded, display it.
            GoogleImage = attributedPhoto.bitmap;
        }
    }

    class AttributedPhoto {
        public final CharSequence attribution;
        public final Bitmap bitmap;

        public AttributedPhoto(CharSequence attribution, Bitmap bitmap) {
            this.attribution = attribution;
            this.bitmap = bitmap;
        }
    }
}

이건 구글에 나와있는 소스를 조금 바꿔서 적용한 것입니다.

처음에는 ArrayList에 다 담아서 차례차례 뿌려주려고 했는데 bitmap 용량이 생각보다 커서 메모리에 문제가

발생하더라구요 그래서 AsyncTask로 받을 때마다 넘겨주려고 하는데 이미지가 하나로만 recyclerview가 채워집니다.

로그로 확인해보니 마지막으로 전달된 ID의 이미지도 아니라서 무엇이 문제인지 모르겠네요

아시는 분이 계시면 꼭 좀 알려주시면 감사하겠습니다.

익명사용자 님이 2018년 1월 3일 질문

1개의 답변

0 추천
GoogleImage 는 전역변수 인건가요?

현재 소스로는 PhotoTask가 mDataset.add(new mainitem(GoogleImage)); 이후에 실행되기 때문에, mDataset에 모두 같은 GoogleImage 가 들어가고 마지막으로 갱신되는 이미지(GoogleImage)로 표시되고 있는 것 같습니다.

mDataset.add(new mainitem(...)); 부분이 PhotoTask 의 onPostExecute() 안으로 들어가야 할 것 같습니다.

mDataset.add(new mainitem(attributePhoto.bitmap)); 이렇게 수정되면 되지 않을까 생각됩니다.
눈빛 (4,120 포인트) 님이 2018년 1월 3일 답변
정답인듯.. 비동기작업에서 사진받아온후 데이터세팅후 갱신하는게 순서입니다 고갱님
그리고 데이터는 전역변수에 넣고 쓰는거 아닙니다 무슨타입인지 모르겠지만 주소값복사되는 타입이면 하나로만 변신되는 멋진상황이 펼쳐지죠
우선 친절한 답변 감사드립니다.

네 GoogleImage는 전역변수입니다.

로그로 확인해보니 확실히 말씀해 주신대로 add가 먼저 실행되었습니다.

이 부분이 문제가 될지 모르고 코드 양이 길어서 조금 잘랐는데 실제로는 sendPlacedata에서 상호명이라던가 주소 등을 받아서 이미지와 함께 add로
전달하고 있습니다.

add 함수를 onPostExecute()로 옮겨보았지만 이미지와 다른 변수값을 받아오지 못했습니다.

혹 이 문제를 해결할 다른 방법을 아신다면 꼭 도와주시면 감사하겠습니다.
다른 변수값도 PID 또는 RecyclerView의 크기 넘기듯이  PhotoTask 안으로 넘길 수는 없는건가요?
네.. 두가지 방법 모두 시도해보고 있는데 데이터가 안 넘어가는지 뜨지않습니다

parameter로도 넘겨보고 asynctask 내부에서 placeid를 통해 받아보려고도 하는데 잘 되지 않습니다

좀 더 고민해 봐야 할 것 같습니다 도움 주셔서 감사합니다.
...