手记

如何获取android手机联系人并按字母展示(二)

如何获取联系人的头像:

这里采用

protected HashMap<Long, SoftReference<Bitmap>> mBitmapCache = new HashMap<Long, SoftReference<Bitmap>>();
protected HashSet<ImageView> mItemsMissingImages = new HashSet<ImageView>();
protected ImageLoaderHandler mHandler;
protected ImageLoader mImageFetcher;

这边是根据photoId去数据库里查询:

public static Bitmap getContactPhoto(Context context, long photoId, BitmapFactory.Options options) {
       if (photoId < 0) {
           return null;
       }

       Cursor cursor = null;
       try {
           cursor = context.getContentResolver().query(
                   ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, photoId),
                   new String[] { Photo.PHOTO }, null, null, null);

           if (cursor != null && cursor.moveToFirst() && !cursor.isNull(0)) {
               byte[] photoData = cursor.getBlob(0);
               // Workaround for Android Issue 8488 http://code.google.com/p/android/issues/detail?id=8488
               if (options == null) {
                   options = new BitmapFactory.Options();
               }
               options.inTempStorage = new byte[16 * 1024];
               options.inSampleSize = 2;
               return BitmapFactory.decodeByteArray(photoData, 0, photoData.length, options);
           }
       } catch (java.lang.Throwable error) {
       } finally {
           if (cursor != null) {
               cursor.close();
           }
       }
       return null;
   }

这个图片是压缩两倍,再转成bitmap的,我们需要考虑如果联系人非常多,我们不能把联系人的所有

头像都实时获取,再把转换得到的bitmap放到imageView中

在getView中,如果我们快速滑动列表,那么肯定不能去做获取图片的操作

if (mScrollState != OnScrollListener.SCROLL_STATE_FLING) {
   sendFetchImageMessage(viewToUse);
}

在检测到scrollview停顿的时候我们再去获取

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
   if (SCROLL_STATE_TOUCH_SCROLL == scrollState) {
              View currentFocus = getCurrentFocus();
              if (currentFocus != null) {
                  currentFocus.clearFocus();
              }
          }
   
   mScrollState = scrollState;
   if (scrollState == OnScrollListener.SCROLL_STATE_FLING) {
      clearImageFetching();
   } else {
      processMissingImageItems(view);
   }
}

然后图片的获取放到单独的线程中进行,通过线程池来管理:

mImageFetcher = new ImageLoader(photoId, view);
synchronized (ContactsList.this) {
   if (sImageFetchThreadPool == null) {
      sImageFetchThreadPool = Executors.newFixedThreadPool(3);
   }
   sImageFetchThreadPool.execute(mImageFetcher);
}

如果在线程中获取到了bitmap那么我们通过handler来进行通知:

Message msg = new Message();
msg.what = FETCH_IMAGE_MSG;
msg.obj = mImageView;
mHandler.sendMessage(msg);

然后在handlermessage中进行处理:

private class ImageLoaderHandler extends Handler {
   @Override
   public void handleMessage(Message message) {
      if (isFinishing()) {
         return;
      }
      switch (message.what) {
      case FETCH_IMAGE_MSG: {
         final ImageView imageView = (ImageView) message.obj;
         if (imageView == null) {
            break;
         }

         final PhotoInfo info = (PhotoInfo) imageView.getTag();
         if (info == null) {
            break;
         }

         final long photoId = info.photoId;
         if (photoId == 0) {
            break;
         }

         SoftReference<Bitmap> photoRef = mBitmapCache.get(photoId);
         if (photoRef == null) {
            break;
         }
         Bitmap photo = photoRef.get();
         if (photo == null) {
            mBitmapCache.remove(photoId);
            break;
         }

         synchronized (imageView) {
            final PhotoInfo updatedInfo = (PhotoInfo) imageView
                  .getTag();
            long currentPhotoId = updatedInfo.photoId;
            if (currentPhotoId == photoId) {
               imageView.setImageBitmap(photo);
               mItemsMissingImages.remove(imageView);
            } else {
            }
         }
         break;
      }
      }
   }

   public void clearImageFecthing() {
      removeMessages(FETCH_IMAGE_MSG);
   }
}

完整代码如下:

    protected void setContactPhoto(Cursor cursor, final ImageView viewToUse, int column) {
      long photoId = 0;

      if (!cursor.isNull(column)) {
         photoId = cursor.getLong(column);
      }

      final int position = cursor.getPosition();
      viewToUse.setTag(new PhotoInfo(position, photoId));

      if (photoId == 0) {
         viewToUse.setImageResource(R.drawable.avatar);
      } else {

         Bitmap photo = null;

         SoftReference<Bitmap> ref = mBitmapCache.get(photoId);
         if (ref != null) {

            photo = ref.get();
            if (photo == null) {
               mBitmapCache.remove(photoId);
            }
         }

         if (photo != null) {
            viewToUse.setImageBitmap(photo);
         } else {
            viewToUse.setImageResource(R.drawable.avatar);
            mItemsMissingImages.add(viewToUse);
            if (mScrollState != OnScrollListener.SCROLL_STATE_FLING) {
               sendFetchImageMessage(viewToUse);
            }
         }
      }
   }
   
   private void processMissingImageItems(AbsListView view) {
      for (ImageView iv : mItemsMissingImages) {
         sendFetchImageMessage(iv);
      }
   }

   protected void sendFetchImageMessage(ImageView view) {
      final PhotoInfo info = (PhotoInfo) view.getTag();
      if (info == null) {
         return;
      }
      final long photoId = info.photoId;
      if (photoId == 0) {
         return;
      }
      mImageFetcher = new ImageLoader(photoId, view);
      synchronized (ContactsList.this) {
         if (sImageFetchThreadPool == null) {
            sImageFetchThreadPool = Executors.newFixedThreadPool(3);
         }
         sImageFetchThreadPool.execute(mImageFetcher);
      }
   }

   public void clearImageFetching() {
      synchronized (ContactsList.this) {
         if (sImageFetchThreadPool != null) {
            sImageFetchThreadPool.shutdownNow();
            sImageFetchThreadPool = null;
         }
      }

      mHandler.clearImageFecthing();
   }

   public void clearMessages() {
      if (mHandler != null) {
         try {
            mHandler.removeCallbacksAndMessages(null);
         } catch (java.lang.Throwable th) {
         }
         mHandler = null;
      }
   }
   
   //image downloader
   private class ImageLoaderHandler extends Handler {
      @Override
      public void handleMessage(Message message) {
         if (isFinishing()) {
            return;
         }
         switch (message.what) {
         case FETCH_IMAGE_MSG: {
            final ImageView imageView = (ImageView) message.obj;
            if (imageView == null) {
               break;
            }

            final PhotoInfo info = (PhotoInfo) imageView.getTag();
            if (info == null) {
               break;
            }

            final long photoId = info.photoId;
            if (photoId == 0) {
               break;
            }

            SoftReference<Bitmap> photoRef = mBitmapCache.get(photoId);
            if (photoRef == null) {
               break;
            }
            Bitmap photo = photoRef.get();
            if (photo == null) {
               mBitmapCache.remove(photoId);
               break;
            }

            synchronized (imageView) {
               final PhotoInfo updatedInfo = (PhotoInfo) imageView
                     .getTag();
               long currentPhotoId = updatedInfo.photoId;
               if (currentPhotoId == photoId) {
                  imageView.setImageBitmap(photo);
                  mItemsMissingImages.remove(imageView);
               } else {
               }
            }
            break;
         }
         }
      }

      public void clearImageFecthing() {
         removeMessages(FETCH_IMAGE_MSG);
      }
   }

   private class ImageLoader implements Runnable {
      long mPhotoId;
      private ImageView mImageView;

      public ImageLoader(long photoId, ImageView imageView) {
         this.mPhotoId = photoId;
         this.mImageView = imageView;
      }

      public void run() {
         if (isFinishing()) {
            return;
         }

         if (Thread.interrupted()) {
            return;
         }

         if (mPhotoId < 0) {
            return;
         }

         Bitmap photo = ContactsUtils.getContactPhoto(getBaseContext(),
               mPhotoId, null);
         if (photo == null) {
            return;
         }

         mBitmapCache.put(mPhotoId, new SoftReference<Bitmap>(photo));

         if (Thread.interrupted()) {
            return;
         }

         Message msg = new Message();
         msg.what = FETCH_IMAGE_MSG;
         msg.obj = mImageView;
         mHandler.sendMessage(msg);
      }
   }
   
}//end of adapter

代码在https://github.com/nickgao1986/StepSport

0人推荐
随时随地看视频
慕课网APP