2

У меня есть ListView, чьими элементами являются фотографии, которые мне нужно загрузить из удаленного API, который я использую для доступа к loopj.Android: асинхронные загруженные растровые изображения случайно не отображаются в ImageView после ImageView.setBitmapDrawable (..)

После того, как loopj загружает данные фото, я использую AsyncTask для обработки данных в масштабированном растровом изображении.

Это, как правило, отлично работает, однако ..

Проблема

В моем методе onPostExecute AsyncTask, я называю setImageBitmap на ImageView. Иногда растровое изображение просто не появляется в ImageView после вызова ImageView.setImageBitmap. Я проверил через журналы, а также отладчик, что ImageView.setImageBitmap действительно вызван нарушением ImageView.

Если я немного прокручиваю список, элемент списка перерисовывается, и изображение загружается из кеша памяти и правильно отображается в ImageView.

Вот мой код:

public void setPersonImage(final ImageView personImageView, final Person p) { 
    personImageView.setImageResource(R.drawable.empty_image); 

    //kills unecessary requests for the imageview's previous occupant photo 
    if(personImageView.getTag() != null) { 
     AsyncHttpClient client = mPhotoRequestsMap.get(p.getEmployeeId()); 
     if(client != null) { 
      client.cancelRequests(getActivity().getApplicationContext(), true); 
      Log.d(TAG, "Cancled photo request for " + String.valueOf(p.getEmployeeId())); 
     } 
    } 

    personImageView.setTag(p.getEmployeeId()); 

    //first attempt to grab photo from cache 
    Bitmap cachedBitmap = mMemoryCache.get(p.getPhotoCacheKey()); 
    if(cachedBitmap != null) { 
     personImageView.setImageBitmap(cachedBitmap); 
     Log.d(TAG, "bitmap for " + String.valueOf(p.getEmployeeId()) + " retrieved from memory cache"); 
    } else { 

     AsyncHttpClient client = ApiWrapper.getPersonImage(180,mUserSession, 
      getActivity().getApplicationContext(), p.getEmployeeId(), 
      new MyAsyncHttpResponseHandler(this) { 
       @Override 
       public void onSuccess(String response) { 
        if(personImageView.getTag().equals(p.getEmployeeId())) { 
         // use async task to process the bitmap off the UI thread 
         AsyncTask<String,Integer,Bitmap> task = new AsyncTask<String,Integer,Bitmap>() { 
          @Override 
          protected Bitmap doInBackground(String... params) { 
           String response = params[0]; 
           byte[] bitmapBytes = ApiWrapper.processImageResponse(response); 
           Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length); 
           Bitmap bmpScaled = ThumbnailUtils.extractThumbnail(bitmap, 180, 180); 
           return bmpScaled; 
          } 

          protected void onPostExecute(Bitmap bitmap) { 
           //set on imageview if tags agree 
           if(personImageView.getTag().equals(p.getEmployeeId())) { 
            Log.d(TAG, "setting image view for " + p.getEmployeeId()); 
            personImageView.setImageBitmap(bitmap); 
            mMemoryCache.put(p.getPhotoCacheKey(), bitmap); 

           } 
           else { 
            Log.d(TAG, "tags don't match after decode bitmap, discarding..."); 
           } 
          } 

         }; 

         task.execute(response); 
        } 
        else { 
         Log.d(TAG, "tags don't match BEFORE decode bitmap employee id: " + p.getEmployeeId() + " tag: " + personImageView.getTag()); 
        } 
       } 


      } 
     ); 

     //create entry in PhotoRequestsMap table 
     mPhotoRequestsMap.put(p.getEmployeeId(), client); 

    } // end if not in cache 
} 

Я попытался назвать недействительными() на ImageView после растровый установлен на нем, но, к сожалению, не решить ..

Я d очень ценю любую помощь или указатели.

Update

Метод GetView из моего адаптера:

public View getView(int position, View convertView, ViewGroup parent) { 

      // If we weren't given a view, inflate one 
      if (convertView == null) { 
       convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_person, null); 
      } 

      Person p = getItem(position); 

      TextView nameTextView = (TextView)convertView.findViewById(R.id.person_ListItemNameTextView); 
      nameTextView.setText(p.getFirstName() + " " + p.getLastName()); 

      TextView idTextView = (TextView)convertView.findViewById(R.id.person_ListItemIdTextView); 
      idTextView.setText(String.valueOf(p.getEmployeeId())); 

      ImageView personImageView = (ImageView)convertView.findViewById(R.id.person_ListItemImageView); 
      setPersonImage(personImageView, p); 

      return convertView; 
     } 
+0

'personImageView' вызывается несколько раз, прежде чем первый AsyncTask закончит, второй перезаписывает его. Попробуйте создать массив объектов. – Shakti

+0

Я предполагаю, что вы повторно используете одни и те же изображения для разных строк списка? Можно ли увидеть метод getView (...) 'от вашего адаптера? –

+0

@ErnirErlingsson Я думаю, что андроид по умолчанию будет перерабатывать сами ImageView. Я кеширую растровые изображения. Я обновил вопрос с помощью метода getView(). Благодаря! – James

ответ

1

Я думаю, что метод .setImageBitmap(Bitmap) работает нормально, вы просто установить его с null.

Проверьте на случай bitmap == null на onPostExecute(Bitmap bitmap). Это также подходит для вашего наблюдения, что изображение появляется при прокрутке, потому что Android вызывает getView(..) снова для видимых строк в это время.

+0

Установленные битовые карты не являются нулевыми. Я проверил это через отладчик, а также сейчас, добавив нулевую проверку, как вы описали. Я вижу тот же результат. Спасибо за попытку, хотя :) – James

+1

Вы пытались раздуть новый просмотр каждый раз, когда вызывается 'getView (..)'? Попробуйте удалить 'if (convertView == null)' и проверить, не исчезла ли проблема (не то, что я рекомендую, просто чтобы проверить, не связана ли проблема с повторным использованием View). –

+0

Я удалил if (convertView == null) и, похоже, работает! Я пытаюсь выяснить, что я должен делать сейчас, поскольку раздувание взгляда каждый раз, вероятно, не является устойчивым подходом? – James

 Смежные вопросы

  • Нет связанных вопросов^_^