【安卓】使用多线程实现ListView中图片的异步加载
2016-08-24 17:36
453 查看
ListView中图片的加载问题十分突出,因为程序读取图片资源十分耗时,而如果把设置图片放到主线程中的话,在下滑时会感觉到明显的卡顿,用户体验非常之差。
于是我想到设置图片这一步肯定不能不再主线程中进行。必须使用异步加载图片来实现。
PS:程序中所有耗时的工作绝对不能再主线程进行,必须异步。
以下是部分核心代码:
这样虽然完成了异步加载,但同时出现了一个十分严重的问题,我将getBitmap方法改为如下形式,以模拟加载延迟:
以上我通过给ImageView设置Tag为mp3Info,并传递给加载图片的函数,当设置图片时判断mp3Info和ImageView标记的是否相同,相同则设置,不相同则不设置.
这样一来就完美的解决了ListView加载图片卡顿的问题,同时也解决了图片异步加载错乱的问题。
于是我想到设置图片这一步肯定不能不再主线程中进行。必须使用异步加载图片来实现。
PS:程序中所有耗时的工作绝对不能再主线程进行,必须异步。
以下是部分核心代码:
package jiaoml.com.music.adapter; import android.content.Context; import android.graphics.Bitmap; import android.os.AsyncTask; import android.os.Handler; import android.os.Message; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; import jiaoml.com.music.R; import jiaoml.com.music.music.Mp3Info; import jiaoml.com.music.utils.MediaUtils; /** * Created by 91905 on 2016/8/17 0017. */ public class FragmentMusicAdapter extends BaseAdapter { private Context context; private ArrayList<Mp3Info> mp3Infos; private static final int LOAD_IMAGE = 1; public FragmentMusicAdapter(Context context) { this.context = context; mp3Infos = MediaUtils.getMp3Infos(context); } @Override public int getCount() { return mp3Infos.size(); } @Override public Object getItem(int i) { return mp3Infos.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View view, ViewGroup viewGroup) { ViewHolder vh; if (view == null) { view = LayoutInflater.from(context).inflate(R.layout.fragment_music_music_item, null); vh = new ViewHolder(); vh.ablum = (ImageView) view.findViewById(R.id.music_ablum); vh.title = (TextView) view.findViewById(R.id.music_title); vh.artist = (TextView) view.findViewById(R.id.music_artist); view.setTag(vh); } else { vh = (ViewHolder) view.getTag(); } Mp3Info mp3Info = mp3Infos.get(i); vh.ablum.setImageResource(R.mipmap.music_default); new ImageLoader().showImageByThread(vh.ablum, mp3Info); vh.title.setText(mp3Info.getTitle()); vh.artist.setText(mp3Info.getArtist()); return view; } class ViewHolder { ImageView ablum; TextView title; TextView artist; } /** * 异步加载图片 */ class ImageLoader { private ImageView imageView; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); imageView.setImageBitmap((Bitmap) msg.obj); } }; /** * 使用多线程实现异步加载 * @param imageView * @param mp3Info */ public void showImageByThread(ImageView imageView, final Mp3Info mp3Info) { this.imageView = imageView; new Thread() { @Override public void run() { super.run(); Message message = Message.obtain(); Bitmap bitmap = getBitmap(mp3Info); message.obj = bitmap; handler.sendMessage(message); } }.start(); } public Bitmap getBitmap(Mp3Info mp3Info) { return MediaUtils.getArtwork(context, mp3Info.getId(), mp3Info.getAlbumId(), true, true); } } }
这样虽然完成了异步加载,但同时出现了一个十分严重的问题,我将getBitmap方法改为如下形式,以模拟加载延迟:
package jiaoml.com.music.adapter; import android.content.Context; import android.graphics.Bitmap; import android.os.AsyncTask; import android.os.Handler; import android.os.Message; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; import jiaoml.com.music.R; import jiaoml.com.music.music.Mp3Info; import jiaoml.com.music.utils.MediaUtils; /** * Created by 91905 on 2016/8/17 0017. */ public class FragmentMusicAdapter extends BaseAdapter { private Context context; private ArrayList<Mp3Info> mp3Infos; private static final int LOAD_IMAGE = 1; public FragmentMusicAdapter(Context context) { this.context = context; mp3Infos = MediaUtils.getMp3Infos(context); } @Override public int getCount() { return mp3Infos.size(); } @Override public Object getItem(int i) { return mp3Infos.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View view, ViewGroup viewGroup) { ViewHolder vh; if (view == null) { view = LayoutInflater.from(context).inflate(R.layout.fragment_music_music_item, null); vh = new ViewHolder(); vh.ablum = (ImageView) view.findViewById(R.id.music_ablum); vh.title = (TextView) view.findViewById(R.id.music_title); vh.artist = (TextView) view.findViewById(R.id.music_artist); view.setTag(vh); } else { vh = (ViewHolder) view.getTag(); } Mp3Info mp3Info = mp3Infos.get(i); vh.ablum.setImageResource(R.mipmap.music_default); vh.ablum.setTag(mp3Info); new ImageLoader().showImageByThread(vh.ablum, mp3Info); vh.title.setText(mp3Info.getTitle()); vh.artist.setText(mp3Info.getArtist()); return view; } class ViewHolder { ImageView ablum; TextView title; TextView artist; } /** * 异步加载图片 */ class ImageLoader { private ImageView imageView; private Mp3Info mp3Info; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (imageView.getTag() == mp3Info) { imageView.setImageBitmap((Bitmap) msg.obj); } } }; /** * 使用多线程实现异步加载 * @param imageView * @param mp3Info */ public void showImageByThread(ImageView imageView, final Mp3Info mp3Info) { this.imageView = imageView; this.mp3Info = mp3Info; new Thread() { @Override public void run() { super.run(); Message message = Message.obtain(); Bitmap bitmap = getBitmap(mp3Info); message.obj = bitmap; handler.sendMessage(message); } }.start(); } public Bitmap getBitmap(Mp3Info mp3Info) { return MediaUtils.getArtwork(context, mp3Info.getId(), mp3Info.getAlbumId(), true, true); } } }
以上我通过给ImageView设置Tag为mp3Info,并传递给加载图片的函数,当设置图片时判断mp3Info和ImageView标记的是否相同,相同则设置,不相同则不设置.
这样一来就完美的解决了ListView加载图片卡顿的问题,同时也解决了图片异步加载错乱的问题。
相关文章推荐
- 安卓代码优化 使用ImageLoader实现图片异步加载
- 使用Volley实现ListView异步加载图片
- ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,下面就说实现方法,先贴上主方法的代码:
- Android实现异步从网络加载图片列表和上拉加载更多、下拉刷新列表(使用xListView框架实现)
- ListView,实现滚动分页效果。实现异步加载URL生成的图片。使得屏幕不卡
- Android实现ListView异步加载图片+缓存+线程池管理
- android中listView实现异步加载网络图片
- iphone中使用NSoperation实现图片异步加载
- android中listView实现异步加载网络图片
- Android 实现ListView异步加载图片
- Android实现ListView异步加载图片
- android 实现listView异步加载图片
- Android实现ListView异步加载图片
- 使用NSoperation 实现异步加载图片
- 使用NSoperation 实现异步加载图片
- Android 如何实现ListView异步加载网络图片
- ListView,实现滚动分页效果。实现异步加载URL生成的图片。使得屏幕不卡
- 转载 Android实现ListView异步加载图片
- Android实现ListView异步加载图片
- Android中ListView使用- 网络图片的异步加载