`

ImageLoader异步加载的原理1--卡顿问题解决

 
阅读更多

            一个多月前在做影音播放器时遇到一个问题,就是在视频列表中显示每个视频第一帧,第一帧是显示出来了,可是滑动的时候出问题了,严重卡顿啊!!!一开始想的是要对图片进行压缩,压缩之后还是卡,然后想到了要开子线程(因为在Android中主线程不能执行耗时操作),把获取视频第一帧的操作放进去,这时候旧问题没有解决,新的问题又出现,图片与视频错位了,查了很多资料最后还是没有很好的解决。            直到今天这个问题终于完美解决了。也就写了ImageLoader类,大概50行代码。我们把获取视频第一帧的操作放入子线程中,根据传入的image(你要显示的在那个位置的图片,也就是Adapter类中 getView方法里通过findViewById获取的),url(视频的路径)

   

package zkx.com.mobileplayer.util;

/**
 * Created by zhang on 2016/10/14.
 */

import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.media.ThumbnailUtils;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;


/**
 * Created by zhang on 2016/11/27.
 */
public class ImageLoader {

    private ImageView mImageView;
    private String mUrl;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (mImageView.getTag().equals(mUrl)) {
                mImageView.setImageBitmap((Bitmap) msg.obj);
            }

        }
    };


    /**
     * @param imageView
     * @param url
     */
    public void showImageByThread(ImageView imageView, final String url) {
        mImageView = imageView;
        mUrl = url;
        new Thread() {
            @Override
            public void run() {
                super.run();
                MediaMetadataRetriever media = new MediaMetadataRetriever();
                media.setDataSource(url);
                Bitmap bitmap = media.getFrameAtTime(3000);
                bitmap = ThumbnailUtils.extractThumbnail(bitmap, 100, 100);
                Message message = Message.obtain();
                message.obj = bitmap;
                mHandler.sendMessage(message);
            }
        }.start();

    }

}

 

 

    然后在你的Adapter类的getView方法里,添上这几句,注意:这里我们iv_icon_video设置了一个唯一的标志tag(通过holder.iv_icon_video.setTag(url) 这段代码,url就是这个唯一的标志tag),相当于给iv_icon_video设置了一个唯一的身份信息,目的就是为避免由于ListView的缓存机制导致图片显示错位,然后调用ImageLoader的showImageByThread方法,传进去holder.iv_icon_video和 url(视频的路径)。然后就是通过showImageByThread方法获取视频第一帧了,我们将获取的bitmap通过Hander发送到了主线程,这样又解决了子线成不能更新UI的问题,然后在handlerMessage方法中处理bitmap,那么我们在Adapter中设置的标志tag就要发挥作用了,我们判断tag是否相同,相同则设置,不同则不处理,那么便解决了错位的问题

 

 

        //设置默认显示的图片
        holder.iv_icon_video.setImageResource(R.drawable.video_default_icon);
        String url = videoItem.getPath();
        holder.iv_icon_video.setTag(url);
        new ImageLoader().showImageByThread(holder.iv_icon_video, url);

 

 还有一点要说的就是在showImageByThread的这两行代码,他们的作用和BaseAdapter里的ViewHolder模式缓存view一样,他们也缓存imageView和url

 

       mImageView = imageView;
       mUrl = url;

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics