每次联网会从服务器端返回50条数据,每条数据包含一张jpg图片,一个String字符串,一个double类型数据。使用之前优化的listview加载图片会闪烁、错乱。后来查找资料发现需要给图片设置tag,然后加载的时候进行对比,tag相等再加载显示。同时需要给图片设置缓存,从网络加载的图片存入缓存中,第二次使用时就不再从网络端获取,而是从缓存中读取。代码如下:
解析从服务器端获取的50条数据:
JSONArray peopleArray;
List<String> scoreList = new ArrayList<>();
List<String> chineseNameList = new ArrayList<>();
List<String> englishNameList = new ArrayList<>();
List<String> peopleFaceList = new ArrayList<>();
private void parseCelebrityJsonResult(String response) {
JSONObject jsonObject = JSON.parseObject(response);
peopleArray = jsonObject.getJSONArray("people");
Log.e("peopleArray",peopleArray.toJSONString());
Double score;
String peopleId;
String chineseName;
String englishName;
JSONObject peopleJsonObj;
String peopleImgUrl;
String scoreStr;
if(peopleArray != null && peopleArray.size() > 0) {
for (int i = 0;i < peopleArray.size();i++){
peopleJsonObj = peopleArray.getJSONObject(i);
score = peopleJsonObj.getDouble("score");
scoreStr = doubleToPercent(score);
Log.e("相似度:",scoreStr);
scoreList.add(scoreStr);
chineseName = peopleJsonObj.getString("chinese_name");
Log.e("相似名字:",chineseName + i);
chineseNameList.add(chineseName);
englishName = peopleJsonObj.getString("english_name");
englishNameList.add(englishName);
peopleId = peopleJsonObj.getString("id");
peopleImgUrl = "http://facde.cn/static/img/celebrity/"+peopleId+".jpg";
Log.e("相似图片:",peopleImgUrl);
peopleFaceList.add(peopleImgUrl);
}
}
initAdapter();
}
=====================
private void initAdapter() {
if(celebAdapter == null) {
celebAdapter = new CelebrityAdapter(CelebrityDetectActivity.this);
}
celebAdapter.notifyDataSetChanged();
lvResult.setAdapter(celebAdapter);
}
=================================
public class CelebrityAdapter extends BaseAdapter{
Context mContext;
LayoutInflater mInflater;
ViewHolder viewHolder;
String name;
LruCache<String,Bitmap> lruCache;
public CelebrityAdapter(Context context){
mContext = context;
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//获取应用程序最大可用内存
int maxMemory = (int) Runtime.getRuntime().maxMemory();
//初始化LruCache并为其分配最大的缓存值
lruCache = new LruCache<String, Bitmap>(maxMemory/4){
@Override
protected int sizeOf(String key, Bitmap value) {
//返回存进缓存的bitmap的大小
return value.getByteCount();
}
};
}
@Override
public int getCount() {
return peopleArray.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
viewHolder = new ViewHolder();
convertView = mInflater.inflate(R.layout.item_listview_celebrity_detect,null);
viewHolder.ivCelebrityFace = (ImageView) convertView.findViewById(R.id.iv_celebrity_face);
viewHolder.tvCelebrityName = (TextView) convertView.findViewById(R.id.tv_celebrity_name);
viewHolder.tvCelebrityScore = (TextView) convertView.findViewById(R.id.tv_celebrity_score);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
progressDialog.dismiss();
viewHolder.ivCelebrityFace.setTag(peopleFaceList.get(position));
if(chineseNameList.get(position).equals("") || chineseNameList.get(position) == null) {
name = englishNameList.get(position);
} else {
name = chineseNameList.get(position);
}
viewHolder.tvCelebrityName.setText("相似人:" + name);
viewHolder.tvCelebrityScore.setText("相似度:" + scoreList.get(position));
new ImageLoaderByLrucache(position,peopleFaceList,peopleFaceList.get(position),viewHolder.ivCelebrityFace,lruCache).imageloadAsyncTask();
return convertView;
}
}
public class ViewHolder{
ImageView ivCelebrityFace;
TextView tvCelebrityName,tvCelebrityScore;
}
==========================
/**
* 从缓存中加载图片
* Created by D.bj on 2017/9/6.
*/
public class ImageLoaderByLrucache{
int position;
ImageView imageView;
LruCache<String,Bitmap> lruCache;
String url;
List<String> urlList;
public ImageLoaderByLrucache(){}
public ImageLoaderByLrucache(int position,List<String> urlList,String url,ImageView imageView,LruCache<String,Bitmap> lruCache){
this.position = position;
this.urlList = urlList;
this.url = url;
this.imageView = imageView;
this.lruCache = lruCache;
}
//通过URL从缓存中获取对应的bitmap
private Bitmap getBitmapFromLruCache(String url){
return lruCache.get(url);
}
//将bitmap设置进缓存中
private void setBitmapIntoLruCache(String url,Bitmap bitmap){
Bitmap bitmap1 = getBitmapFromLruCache(url);
if(bitmap1 == null) {
lruCache.put(url,bitmap);
}
}
public void imageloadAsyncTask(){
//加载图片之前先判断缓存中是否有该图片,如果有直接使用缓存中的,如果没有通过网络加载
Bitmap bitmap = getBitmapFromLruCache(url);
if(bitmap != null) {
if(imageView.getTag().equals(url)) {
imageView.setImageBitmap(bitmap);
}
} else {
new LoadBitmapFromUrl(position,imageView).execute(urlList.get(position));
}
}
public class LoadBitmapFromUrl extends AsyncTask<String,Void,Bitmap> {
int position;
ImageView imageView;
public LoadBitmapFromUrl(){}
public LoadBitmapFromUrl(int position,ImageView imageView){
this.position = position;
this.imageView = imageView;
}
@Override
protected Bitmap doInBackground(String... params) {
Log.e("params-0:",params[0]);
return loadImageFromNetwork(params[0]);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if(imageView.getTag().equals(urlList.get(position))) {
imageView.setImageBitmap(bitmap);
} else {
imageView.setImageBitmap(null);
}
}
}
private Bitmap loadImageFromNetwork(String url) {
Bitmap bitmap = simpleNetworkImage(url);
if(bitmap == null) {
Log.i("","");
}
return bitmap;
}
private Bitmap simpleNetworkImage(String url) {
Bitmap imgBitmap = null;
try {
URL picUrl = new URL(url);
imgBitmap = BitmapFactory.decodeStream(picUrl.openStream());
//判断缓存中是否存在该数据
if(getBitmapFromLruCache(url) == null) {
//将通过网络加载的图片放入缓存中
setBitmapIntoLruCache(url,imgBitmap);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return imgBitmap;
}
}